为什么当 @Input() 更新数据 Angular 8 时 ngOnChanges() 不触发?

Amb*_*nna 6 javascript lifecycle typescript ecmascript-6 angular

父组件.html

<parent-comp [data]="mydata"> </parent-comp>
Run Code Online (Sandbox Code Playgroud)

父组件.ts

this.service.abc$
        .takeUntil(this.ngUnsubscribe.asObservable())
        .subscribe((data: myType[]) => {
            this.mydata= data;
        });
Run Code Online (Sandbox Code Playgroud)

子组件.ts

@Input data;
Run Code Online (Sandbox Code Playgroud)

在类下我有以下代码

<parent-comp [data]="mydata"> </parent-comp>
Run Code Online (Sandbox Code Playgroud)

@Input data现在我希望每当我从父组件接收到子组件的最新数据时,我的ngOnChanges函数就应该触发并在控制台中打印数据。

但不幸的是ngOnChanges函数不会再次触发。组件初始化时仅触发一次

如果有人想要更多详细信息,请告诉我!

谢谢!

Mic*_*l D 9

由于缺乏进一步的信息,我会做出明智的猜测,它@Input data要么是一个数组,要么是一个对象。

根据文档ngOnChanges是:

当指令的任何数据绑定属性发生更改时调用的生命周期挂钩。

但它没有说明应该如何更改该属性。一般来说,只有当对属性的引用发生更改时才会触发挂钩。

考虑以下情况,例如。

父组件控制器

mydata = [];

updateMyData(value: any) {
  this.mydata.push(value);
}
Run Code Online (Sandbox Code Playgroud)

父组件模板

<app-child [data]="mydata"></app-child>
Run Code Online (Sandbox Code Playgroud)

子组件控制器

@Input() data: any;

ngOnChanges(changes: SimpleChanges) {
  console.log(changes);
}
Run Code Online (Sandbox Code Playgroud)

现在您希望ngOnChanges每次updateMyData()在父组件中调用该函数时都会触发 。但对变量的引用mydata永远不会改变。所以钩子不会被触发。有多种方法可以强制更改检测器触发挂钩。

方法一:@Input装饰器绑定到setter,而不是直接绑定到变量。已经在答案中讨论过。

方法二: 使用扩展语法在父组件中重新赋值变量。

父组件控制器

mydata = [];

updateMyData(value: any) {
  this.mydata = [...this.mydata, value];
}
Run Code Online (Sandbox Code Playgroud)

您也可以对对象使用相同的方法。


Min*_*hah 1

您可以在 Angular 中对 @Input 使用 setter 和 getter 方法。请参考以下几行:

private _data: any;
  @Input()
  set data(data) {
    this._data = data;
    console.log(this._data);
  };
Run Code Online (Sandbox Code Playgroud)

仅通过 setter 方法,您也可以调用任何其他方法,并且可以从那里运行您想要的任何逻辑。