-->

Why angular 2 ngOnChanges not responding to input

2019-02-12 00:15发布

问题:

My angular application stuck with a issue, i used input as array and pushed a value to the array when the click event arise. But the ngOnChanges not firing when the array push is done. Is there a way to fire ngOnChange

My Code is ts file is

@Component({
  selector: 'adv-search',
  templateUrl: './app/modules/result.html'
})

export class InputComponent {
  @Input() metas:any=[];

  ngOnChanges() {
    console.log(this.metas);
  }
}

My Selector Tag

<adv-search [metas] = "metaIds"></adv-search>

Click Event Code

insertIds(id:any) {
   metaIds.push(id);
}

回答1:

Angular change detection only checks object identity, not object content. Inserts or removals are therefore not detected.

What you can do is to copy the array after each update

insertIds(id:any) {
  this.metaIds.push(id);
  this.metaIds = this.metaIds.slice();
}

or use IterableDiffer to check for changes inside InputComponent in ngDoCheck like NgFor does.



回答2:

@GünterZöchbauer 's answer is completely correct. However, I would like to add a alternative/supplement to copying the whole array. Using the same example from the question.

<adv-search [metas] = "metaIds"></adv-search>

altered to

<adv-search [metas] = "{trackBy: metaIds.length, metaIds: metaIds}"></adv-search>

Where length here is the equivalent of the *ngFor trackBy function for the component. With this the ngOnChanges occurs with content length changes.

If used in combination with the *ngFor trackBy method there should be some performance benefits as the whole array's bound templates are not recalculated (no screen/content flickering).



回答3:

If you reassign your metaIds array, the ngOnChanges lifecycle event will be fired. You can deconstruct your array into a new array.

insertIds(id:any){
    this.metaIds = [...this.metaIds, id];
}