angular - 如果@Input 正在接收对象,ngOnChanges 不会触发
问题描述
父组件模板:
<my-component [param]="whatever"></my-component>
父组件代码:
whatever = { value1: 0, value2: 1, value3: 'foo' };
子组件代码:
@Input() public param: any;
ngOnChanges() {
console.log('Received input: ', param);
}
这是行不通的。任何更改whatever
都不会被子组件注意到并且ngOnChanges
不会触发。
如果我尝试使用 setter,它也不起作用:
@Input() set param(value) {
console.log(value);
}
如果我尝试在父组件中运行手动区域更新,它也无济于事。
显然@Input()
只能检测到对象的结构何时发生了变化,而不能检测到它的值。
那么如何将对象作为@Input()
属性传递并让子组件检测值变化呢?
解决方案
OnChanges生命周期挂钩在@Input
属性值更改时触发。在对象的情况下,该值是对象引用。如果对象引用没有改变,OnChanges
则不会触发。
强制更改检测的一种可能技术是在修改属性值后设置新的对象引用:
this.whatever.value1 = 2;
this.whatever.value2 = 3;
this.whatever = Object.assign({}, this.whatever);
然后ngOnChanges
可以使用事件处理程序来监视更改:
ngOnChanges(changes: SimpleChanges) {
for (let propName in changes) {
let chng = changes[propName];
let cur = JSON.stringify(chng.currentValue);
console.log(propName, cur);
}
}
作为替代方案,如果@Input
装饰 getter/setter 属性,则可以在 setter 中监视更改:
private _param: Object;
@Input() get param(): Object {
return this._param;
}
set param(value: Object) {
console.log("setter", value);
this._param = value;
}
请参阅此 stackblitz以获取演示。
推荐阅读
- r - 将时间戳转换为日期、时间、小时、分钟
- vba - PowerPoint VBA - 基于水平轴数据标签的图表颜色
- reactiveui - ReactiveUI WhenActivated 在 Android 上抛出 ObjectDisposedException
- python - 用另一列中的值替换熊猫列值
- python - 连接到 Firestore 上的辅助数据库
- python - Can't record screen using mss and cv2
- javascript - Angular 2/4/5 (Not AngularJS) :- how can I take .offset().top of an element?
- xml - 使用 shell 脚本更新同一 xml 文件中的文本
- twitter-bootstrap - css3:制作标题导航菜单
- angular - Angular 6 对 .NET Web API 的跨域 POST 请求返回 401(未经授权)