Reputation: 1952
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);
}
Upvotes: 45
Views: 27926
Reputation: 191
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];
}
Upvotes: 14
Reputation: 121
@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).
Upvotes: 12
Reputation: 658087
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.
Upvotes: 88