Tengo una lista de una matriz (fuente de datos) en la que estoy realizando operaciones de Agregar y Eliminar. Pasé una matriz (fuente de datos) en el componente secundario y agregué * ngFor loop en el elemento secundario. Array He pasado como getter setter para detectar el cambio @Input.
Este es mi componente de aplicación :
<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>
En ChildComponent (pestañas verticales):
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; }
El problema es que cuando agrego un nuevo elemento en la matriz, no está llamando al método de cambio @Input del setter. Cuando estoy eliminando un elemento, funciona bien y llamo @Input change.
Nota: tengo muchas propiedades como entrada en un escenario real, así que no quiero usar ngOnChanges()
Aquí hay un ejemplo que he creado: https://stackblitz.com/edit/angular-vertical-tabs-component-split-yzynef
Angular solo verifica si la referencia ha cambiado; si no ha cambiado desde la última verificación, no se llamará al setter.
En app.component.ts
:
let nextItem = this.dataSource.length; this.dataSource.push({ id: nextItem.toString(), text: 'item ' + nextItem.toString(), icon: 'settings', });
Aquí agrega algo a su matriz en lugar de crear una nueva matriz y asignarla a dataSource
.
En vertical-tabs.ts
:
onDelete(item, index) { this.dataSource = this.dataSource.filter((x) => x !== item); }
Aquí crea una nueva matriz y la asigna a dataSource
.
Es por eso que la eliminación funciona como espera, pero la adición no. Copiar la matriz y asignarla a dataSource
debería resolver su problema:
let nextItem = this.dataSource.length; this.dataSource = [ ...dataSource, { id: nextItem.toString(), text: 'item ' + nextItem.toString(), icon: 'settings', } ];