I have a list of an array(dataSource) on which I am performing Add and Delete operations. I have passed an array(dataSource) in the child component and added *ngFor loop in the child. Array I have passed as getter setter for detect @Input change.
This is my AppComponent :
<div>
<vertital-tabs
[config]="config"
[dataSource]="dataSource" <-- Array changes I want to detect in Child
[(selectedItem)]="selectedItem">
</vertital-tabs>
<div style="background-color: yellow;margin: 10px">
{{ selectedItem | json }}
</div>
</div>
In ChildComponent (vertical-tabs) :
get dataSource(): any {
return this._dataSource;
}
@Input() set dataSource(value: any) {
this._dataSource = value;
// Not called this on Add New button even if Input Datasource is changed.
// I want this to be called on Add New Item button click....
debugger;
}
Problem is that when I am adding a new item on the array, it is not calling the setter @Input change method. When I am deleting an item it is working fine and call @Input change.
Note: I have lot of properties as an Input in real scenario so I don't want to use ngOnChanges()
Here is an example I have created: https://stackblitz.com/edit/angular-vertical-tabs-component-split-yzynef
CodePudding user response:
Angular only checks whether the reference has changed - if it has not changed since the last check the setter will not be called.
In app.component.ts
:
let nextItem = this.dataSource.length;
this.dataSource.push({
id: nextItem.toString(),
text: 'item ' nextItem.toString(),
icon: 'settings',
});
Here you add something to your array instead of creating a new array and assigning it to dataSource
.
In vertical-tabs.ts
:
onDelete(item, index) {
this.dataSource = this.dataSource.filter((x) => x !== item);
}
Here you create a new array and assign it to dataSource
.
That's why deletion works as you expect, but adding doesn't. Copying the array and assigning it to dataSource
should solve your problem:
let nextItem = this.dataSource.length;
this.dataSource = [
...dataSource,
{
id: nextItem.toString(),
text: 'item ' nextItem.toString(),
icon: 'settings',
}
];