Angolare 2: come rilevare i cambiamenti in un array? (proprietà @input)

Ho un componente padre che recupera una matrice di oggetti usando una richiesta Ajax.

Questo componente ha due componenti figlio: uno di questi mostra gli oggetti in una struttura ad albero e l’altro ne rende il contenuto in un formato tabella. Il genitore passa l’array ai figli attraverso una proprietà @input e visualizzano il contenuto correttamente. Tutto come previsto

Il problema si verifica quando si modifica un campo all’interno degli oggetti: i componenti secondari non vengono informati di tali modifiche. Le modifiche vengono triggerste solo se si riassegna manualmente la matrice alla sua variabile.

Sono abituato a lavorare con Knockout JS e ho bisogno di ottenere un effetto simile a quello degli ObservableArray.

Ho letto qualcosa su DoCheck ma non sono sicuro di come funzioni.

OnChanges Lifecycle Hook si triggers solo quando cambia l’istanza della proprietà di input.

Se si desidera verificare se un elemento all’interno della matrice di input è stato aggiunto, spostato o rimosso, è ansible utilizzare IterableDiffers all’interno di DoCheck Lifecycle Hook come segue:

 constructor(private _iterableDiffers: IterableDiffers) { this.iterableDiffer = this._iterableDiffers.find([]).create(null); } ngDoCheck() { let changes = this.iterableDiffer.diff(this.inputArray); if (changes) { console.log('Changes detected!'); } } 

Se è necessario rilevare le modifiche negli oggetti all’interno di un array, sarà necessario scorrere tutti gli elementi e applicare KeyValueDiffers per ciascun elemento. (Puoi farlo in parallelo con il controllo precedente).

Visita questo post per ulteriori informazioni: Rileva le modifiche negli oggetti all’interno dell’array in Angular2

Leggi l’articolo che segue, non perdere oggetti mutabili vs immutabili.

Il problema chiave è che si muta gli elementi dell’array, mentre il riferimento dell’array rimane lo stesso. E il rilevamento delle modifiche Angular2 controlla solo il riferimento dell’array per rilevare le modifiche. Dopo aver compreso il concetto di oggetti immutabili, capiresti perché hai un problema e come risolverlo.

Uso il redux store in uno dei miei progetti per evitare questo tipo di problemi.

https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html

È ansible utilizzare IterableDiffers

È usato da * ngFor

 constructor(private _differs: IterableDiffers) {} ngOnChanges(changes: SimpleChanges): void { if (!this._differ && value) { this._differ = this._differs.find(value).create(this.ngForTrackBy); } } ngDoCheck(): void { if (this._differ) { const changes = this._differ.diff(this.ngForOf); if (changes) this._applyChanges(changes); } } 

È sempre ansible creare un nuovo riferimento alla matrice unendola con una matrice vuota:

 this.yourArray = [{...}, {...}, {...}]; this.yourArray[0].yourModifiedField = "whatever"; this.yourArray = [].concat(this.yourArray); 

Il codice sopra cambierà il riferimento dell’array e attiverà il meccanismo OnChanges nei componenti figli.

LK “Ho

Se non ti dispiace usare la libreria esterna, usa WatchJS per questo:

https://github.com/melanke/Watch.JS/

 import * as WatchJS from 'melanke-watchjs'; var watch = WatchJS.watch; 

 myArray : myObject[] = []; // on constructor or ngOnInit watch(this, "myArray", (prop, action, newvalue, oldvalue) => { // detected change! do stuff here ... }); 

È lavoro per me:

 @Component({ selector: 'my-component', templateUrl: './my-component.component.html', styleUrls: ['./my-component.component.scss'] }) export class MyComponent implements DoCheck { @Input() changeArray: MyClassArray[]= []; private differ: IterableDiffers; constructor(private differs: IterableDiffers) { this.differ = differs; } ngDoCheck() { const changes = this.differ.find(this.insertedTasks); if (changes) { this.myMethodAfterChange(); } 

}