Angular 5中子组件的ngOnChanges只触发一次

8
我有一个包含复杂输入(一些图表数据)的子组件。我通过Angular 5中的@Input()装饰器从父组件发送此图表数据,获取API响应后发送。因此,每次在父组件上更改时,我需要根据API响应同步图表,因此需要使用OnChange生命周期。但不幸的是,我无法使其正常工作。我尝试使用设置具有基本数字类型的虚拟输入字段并将其增加,但徒劳无功。以下是我的实现:
子图表组件:
export class ChartComponent implements OnInit, OnChanges {

  @Input() chartData;
  @Input() triggerChart;

  ngOnChanges(changes: SimpleChanges) {
    console.log(changes);
  }

}

Parent component html:

<app-chart [chartData]="chartData" [triggerChart]="triggerChartData"></app-chart>
<input [(ngModel)]="triggerChartData" type="hidden">

Parent component:

this.chartService.getChartData(params).subscribe(res => {
  this.chartData = res;
  this.triggerChartData++;
});

PS:正如标题所示,ngOnChanges仅在组件初始化时使用未定义值时触发一次。


你确定你的ChartData在父组件中被解析了吗? - joshrathke
是的,我能够将API响应记录到控制台。但是,我注意到triggerChartData没有增加。它记录了NaN。 - Mehdi Benmoha
尝试将输入属性记录到DOM中,而不是使用handlebars在子组件中使用{{ chartData | json }}。对象对于变更检测来说比较棘手,因为输入仅会将对象作为引用传递,这意味着变更检测无法检测到超出父组件中定义的对象的初始引用之外的更改。 - joshrathke
1
在触发 triggerChartData++ 渲染 NaN 的情况下,尝试使用数字值初始化该属性:triggerChartData: number = 0。然后使用 ++ 应该可以正常工作。 - joshrathke
1
阅读此内容 https://dev59.com/e1kT5IYBdhLWcg3wc_NR - 尤其是编辑“EDIT 2017-07-25:...” - Hoang Duc Nguyen
@HoangDucNguyen 谢谢!!! 我使用了ChangeDetectorRef,它起作用了!!! 你能为将来的人们做一个答案吗?还是我应该自动回答带有工作代码的问题? - Mehdi Benmoha
2个回答

12

感谢@HoangDucNguyen,以下是可行的代码:

this.chartService.getChartData(params).subscribe(res => {
  this.chartData = res;
  this.changeDetectorRef.detectChanges();
});

当变量在angular上下文之外发生变化时(这里是rxJs上下文),Angular无法检测到变量的更改。因此,您需要手动触发detectChanges Angular方法。当然,您需要从@angular/core导入ChangeDetectorRef类并在构造函数中注入它。

官方文档:https://angular.io/api/core/ChangeDetectorRef


1
很好,你非常周到 :) - Hoang Duc Nguyen
哇!!花了很多时间,问题终于解决了!!谢谢 :) - Zahid Rasheed

0

你必须使用 changeDetectorRef

this.cd.markForCheck();
if (!this.cd['destroyed']) {
    this.cd.detectChanges();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接