如果@Input正在接收对象,则不触发ngOnChanges

问题描述 投票:2回答:3

父组件模板:

<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()属性传递并让子组件检测值更改?

angular angular6 angular2-template
3个回答
1
投票

@Input属性值更改时会触发角度变化检测。

因此,要在对象的情况下触发更改检测,您可以使用spread运算符作为输入传递对象的副本。

例如。 someVar = {key: value}这是@Input()变量,所以传球就好

<app-sample [someVar]="{...someVar}" ></app-sample>

{...VARIABLE}


2
投票

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;
}

有关演示,请参阅this stackblitz


1
投票

像这样:

@Input() public param: any;
ngOnChanges(changes: SimpleChanges): void {
    // Do your check here
    console.log(changes.param.previousValue);
}

使用更改可以访问previousValue和currentValue。

© www.soinside.com 2019 - 2024. All rights reserved.