实际上,当 angular2+ 的子组件中的输入发生变化时,有两种方法可以检测和采取行动:
- 您可以使用旧答案中也提到的ngOnChanges() 生命周期方法:
@Input() categoryId: string;
ngOnChanges(changes: SimpleChanges) {
this.doSomething(changes.categoryId.currentValue);
// You can also use categoryId.previousValue and
// categoryId.firstChange for comparing old and new values
}
文档链接:ngOnChanges、 SimpleChanges、 SimpleChange
演示示例:看看这个 plunker
- 或者,您还可以使用输入属性设置器,如下所示:
private _categoryId: string;
@Input() set categoryId(value: string) {
this._categoryId = value;
this.doSomething(this._categoryId);
}
get categoryId(): string {
return this._categoryId;
}
文档链接:看这里。
演示示例:看看这个 plunker。
您应该使用哪种方法?
如果您的组件有多个输入,那么,如果您使用 ngOnChanges(),您将在 ngOnChanges() 中一次获得所有输入的所有更改。使用这种方法,您还可以比较已更改的输入的当前值和以前的值,并采取相应的措施。
但是,如果您只想在特定的单个输入更改时执行某些操作(并且您不关心其他输入),那么使用输入属性设置器可能会更简单。但是,这种方法没有提供一种内置方法来比较更改输入的先前值和当前值(您可以使用 ngOnChanges 生命周期方法轻松完成)。
编辑 2017-07-25:在某些情况下,角度变化检测可能仍然不会触发
通常,只要父组件更改它传递给子组件的数据,setter 和 ngOnChanges 的更改检测就会触发,前提是数据是 JS 原始数据类型(string, number, boolean)。但是,在以下情况下,它不会触发,您必须采取额外的措施才能使其工作。
如果您使用嵌套对象或数组(而不是 JS 原始数据类型)将数据从父级传递给子级,则更改检测(使用 setter 或 ngchanges)可能不会触发,正如用户回答中提到的:muetzerich。对于解决方案看这里。
如果您在角度上下文之外(即外部)改变数据,那么角度将不知道这些变化。您可能必须在组件中使用 ChangeDetectorRef 或 NgZone 以从角度感知外部变化,从而触发变化检测。参考这个。