我有以下代码。父组件使用
@Input
指令向子组件发送一些数据:
父 HTML
<div>
<my-timeline
[data]="data">
</my-timeline>
</div>
在Parent TS中有一个服务向
data
提供数据
家长TS
data=[];
...
this.service.getData().subscribe(res => {
res.map(item=>{
this.data.push({
...
});
})
})
孩子收到的信息是
儿童TS
@Input data;
eventArray=[];
ngOnInit() {
console.log("called"); // called only for the first time
createTimeline(data[0].id); // called only for the first time
}
createTimeline(id) { // called only for the first time
this.eventArray.push(.....)
}
子 HTML
<p-timeline [value]="eventArray">
...
</p-timeline>
问题是
p-timeline
继续显示旧事件,即第一次加载的事件。因为父级的后续数据更改不会导致子级中的 ngOnIt 运行。这就是为什么 createTimeline
再也没有被调用过。请参与。
为了检测 @Input 属性的更改,您可以实现以下操作之一:
private _data: any;
@Input()
set data(value: any) {
this._data= value;
if(this._data)
this.createTimeline(this._data[0].id)
}
get data(): any{
return this._data;
}
OnChanges 生命周期挂钩 -
首先解释一下什么是
OnChanges
钩子?
来自 Angular.io:
OnChanges 是一个生命周期钩子,当任何数据绑定属性 指令更改。定义一个 ngOnChanges() 方法来处理 变化。
让我们实现 OnChanges 生命周期挂钩,如下所示:
@Component({...})
export class SelectedPlayerComponent implements OnChanges {
@Input() data;
ngOnChanges(changes: SimpleChanges) {
if(changes.data)
{
this.createTimeline(changes.data.currentValue[0].id);//the new value that's changed
}
}
}
感谢 Todd Motto 关于 检测角度输入变化
的好文章在所有组件上使用
ChangeDetectionStrategy.Default
或使用不可变数据方法,例如
this.data = [...this.data, {//item}];
可以在 docs 中阅读它,以及 Angular
ngOnInit
的工作原理