我有一个与以下代码有关的问题:
儿童
export class ChildComponent implements OnChanges {
public @Input() data: string[];
ngOnChanges(changes: SimpleChanges) {
console.log('I am here');
}
}
子模板
{{ data | json }} // This is not necessary. The behaviour is the same with or without it.
<div *ngFor="let item of data">
{{ item }}
</div>
父母
export class AppComponent implements OnInit {
public test: string[] = ['hello'];
ngOnInit() {
console.log('I am here');
}
public addItem() {
this.test.push('sample');
}
}
父模板
<child-component [data]="test"></child-component>
<button (click)="addItem()">Add</button>
我知道ngOnChanges仅在数组引用更改时才会调用,并且如果我将元素推到数组中则不会调用它。以下引起了我的注意。当我按下添加按钮时,新元素将添加到数组中,并且视图已正确更新。我使用json管道和ngFor来证明它正确更新。如果我不使用json管道,则行为是相同的。因此,如果视图更新正确,为什么不调用ngOnChanges?谁负责检测是否有更改要在视图中显示?
总而言之,疑问如下。为什么当将元素添加到数组时,视图会正确更新,但是为什么不调用ngOnChanges?
更改检测是否以其他方式进行?
如您所知,ngOnChanges
是为处理@Input()
属性的任何更改而设计的(如果将新数据简单地馈送到组件可能会产生一些其他影响,并且无法通过组合set
来完成)和@Input()
)。因此,它仅关注@Input()
更改。同样如您所知,只有在引用将要更改的情况下,此信息才会更新。
并且您的组件无论如何都会得到更新,因为:
OnPush
更改检测策略(因此它不仅会在任何@Input()
的引用更改或在任何可观察/事件上更改)json
管道不纯-docs)。尝试删除它,看看会发生什么。请接受一个事实,这只是一个理论。但我很确定这是对的。
编辑:哦,似乎在官方文档here中有一个完美的例子:
...飞行英雄会在您添加英雄时显示更新,即使您更改了英雄数组。