Angular 2 input propery changes is not detect by a

2019-09-04 23:22发布

问题:

I use DoCheck for detecting important changes in my input property that passed from ngFor. It's works normally. But when I did some changes (remove one item from array that iterate by ngFor) my child component don't see any changes and not re-render itself.

Maybe I do something wrong?

 ngDoCheck() {
    console.log('zz');
    var changes = this._differ.diff(this.schedulerData);
    console.log(changes);
    if(changes) {
        changes.forEachAddedItem(r => {
            console.log(r);
            if (r.key === 'tasks') this.launchScheduler();
        });
    }
}

ngOnInit() {
        console.log(this.schedulerData);

    }  /* !ngOnInit */


ngOnChanges(changes: {[propertyName: string]: SimpleChange}) {

    for (let propName in changes) {
     if (propName === 'schedulerData') {
console.log(changes[propName]);

     }
    }
}

回答1:

Change detection doesn't detect updates within objects or arrays by default but when object references change.

If you want to bypass this behavior, using ngDoCheck like you do is the right approach. In your case, it's the normal behavior:

  • You listen to array update from the ngDoCheck method leveraging the IterableDiffers class
  • The ngOnChanges method isn't called since it's triggered by the default change detector (that detects object reference changes).

Otherwise for your information from the doc:

Note that a directive typically should not use both DoCheck and OnChanges to respond to changes on the same input. ngOnChanges will continue to be called when the default change detector detects changes, so it is usually unnecessary to respond to changes on the same input in both hooks. Reaction to the changes have to be handled from within the ngDoCheck callback.



回答2:

Change detection is not triggered when you add or remove to an array. This is because the array reference does not change. (So just adding something or removing something does not "change" the array according to change detection).

If you want to have change-detection notice these changes, you need to alter the reference to the array. For example, the easiest way I can think of this is by using array.sliceon your array. This method call will return a new array, if you assign your old array to that, you will have a new reference, and change detection will notice this.