Actually, there are two ways of detecting and acting upon when an input changes in the child component in angular2+ :
- 您可以使用旧答案中提到的ngOnChanges() lifecycle method:
@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
}
Documentation Links: ngOnChanges, SimpleChanges, SimpleChange
Demo Example: Look at this plunker
- 或者,您也可以使用input property setter,如下所示:
private _categoryId: string;
@Input() set categoryId(value: string) {
this._categoryId = value;
this.doSomething(this._categoryId);
}
get categoryId(): string {
return this._categoryId;
}
文档链接:查看here.
演示示例:看this plunker.
WHICH APPROACH SHOULD YOU USE?
如果您的组件有多个输入,那么如果您使用ngOnChanges(),您将在ngOnChanges()中一次获得所有输入的所有更改.使用此方法,您还可以比较已更改的输入的当前值和以前的值,并采取相应的操作.
然而,如果您只想在某个特定的单一输入发生更改时执行某些操作(并且不关心其他输入),那么使用输入属性设置器可能会更简单.然而,这种方法并没有提供一种内置的方法来比较更改输入的先前值和当前值(使用ngOnChanges lifecycle方法可以很容易地做到这一点).
EDIT 2017-07-25: ANGULAR CHANGE DETECTION MAY STILL NOT FIRE UNDER SOME CIRCUMSTANCES
通常,每当父组件更改传递给子组件provided that the data is a JS primitive datatype(string, number, boolean)的数据时,setter和ngOnChanges的更改检测都会触发.但是,在以下情况下,它不会启动,您必须采取额外的措施才能使其工作.
如果您使用嵌套对象或数组(而不是JS基元数据类型)将数据从父级传递到子级,则可能不会触发更改检测(使用setter或ngchange),这在user:muetzerich的回答中也有提到.要获得解决方案,请查看here个.
如果在angular上下文之外(即外部)对数据进行变异,angular将不知道这些变化.您可能必须在组件中使用ChangeDetectorRef或NgZone,以了解外部变化,从而触发变化检测.参考this.