Angular 2+: дочерние компоненты изменяются, но пользовательский интерфейс не показывает измененное значение? - PullRequest
0 голосов
/ 19 июня 2019

У меня есть дочерний TestComponent компонент следующим образом:

import { Component, OnInit, Input } from '@angular/core';
import { ApiService } from '../../../api.service';

@Component({
  selector: 'app-test',
  templateUrl: './test.component.html'
})
export class TestComponent implements OnInit {

  constructor(private apiService: ApiService) { }

  testDisplayMessage = 'No data to show';

  ngOnInit() {
  }

  getMessage(param: string) {
    this.callingTest = true;
    this.apiService.getTest( param ).subscribe( data => {
      this.setTestDisplayMessage( data );
      this.callingTest = false;
    }, err => {
      console.log( JSON.stringify( err ) );
      this.setTestDisplayMessage( 'Failed to get data' );
      this.callingTest = false;
    } );
  }

  setTestDisplayMessage( message: string ) {
    this.testDisplayMessage = message;
  }
}

содержимое test.component.html

<p style="padding: 10px;">{{ testDisplayMessage }}</p>

Использование в родительском компоненте:

Trigger JSКод в родительском компоненте при нажатии кнопки,

import { TestComponent } from './test/test.component';
....

.....
@Component({
  providers: [ TestComponent ],
  templateUrl: 'parent.component.html'
})
export class ParentComponent implements OnInit {
  ...
  constructor(private testComponent: TestComponent) { }
  ...
  // Button on parent template triggers this method
  getMessage() {
    this.testComponent.getMessage('Hello');
  }
  ...
}

HTML-тег, добавленный в родительский компонент,

<app-test></app-test>

Когда я отлаживаю выше точки триггера кода, вызов setTestDisplayMessage() происходит в поле testDisplayMessage в TestComponent изменяется, но пользовательский интерфейс показывает старое сообщение 'No data to show', почему сообщение об изменении не отражается в шаблоне пользовательского интерфейса?Или это не так, как это должно привыкнуть?Должен ли я использовать @Input

Обновление:

Исходя из указателей, приведенных в следующих ответах, а также в разделах комментариев, я изменил свой компонент как @ViewChild, поэтомуВ вышеприведенном родительском компоненте вместо передачи дочернего компонента в качестве аргумента в конструктор я объявил его как дочерний компонент, используя @ViewChild, поэтому код изменяется следующим образом:

Ранее неправильный код

constructor(private testComponent: TestComponent) { }

Решение

@ViewChild(TestComponent)
testComponent: TestComponent;

Я нашел эта статья полезной.

Ответы [ 4 ]

3 голосов
/ 19 июня 2019

Использование @ViewChild()

В html-файле:

<app-test #childComp></app-test>

В родительском файле component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
....

.....
@Component( {
templateUrl: 'parent.component.html'
} )
export class ParentComponent implements OnInit {

@viewChild('childComp') childComp: any;
constructor() { }
...
// Button on parent template triggers this method
getMessage() {
   this.childComp.getMessage('Hello');
}
...
}
0 голосов
/ 19 июня 2019

Обновление:

Исходя из указателей, приведенных в следующих ответах, а также в разделах комментариев, я изменил свой компонент как @ViewChild, поэтому в вышеприведенном родительском компоненте вместо передачи дочернего компонента в качестве аргумента конструктору я объявил его как дочерний компонент с помощью @ViewChild, поэтому код изменяется следующим образом:

Ранее неправильный код

constructor(private testComponent: TestComponent) { }

Решение

@ViewChild(TestComponent)
testComponent: TestComponent;

Я нашел эта статья полезной.

0 голосов
/ 19 июня 2019

В принципе, ваш подход неверен, используйте Input () или Services для обмена данными между компонентами.

однако, если вы хотите, чтобы ваш код работал, ниже может работать

  1. детектор изменений импорта

    конструктор ( private cdRef: ChangeDetectorRef ) { }

примечание: ссылка на импорт -> import {ChangeDetectorRef} из '@ angular / core';

  1. выполнить обнаружение изменений после обновления значения

    setTestDisplayMessage( message: string ) {
        this.testDisplayMessage = message;
        this.cdRef.detectChanges();
      }
    

Надеюсь, это поможет

0 голосов
/ 19 июня 2019

обязательно используйте @Input (), но при заданном методе

@Input()
set someProperty(value) {
  // do some code
}

теперь каждый раз, когда вы передаете новое значение, код будет запускаться

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...