2016-03-02 15 views
7

Utilizzo di Angular 2 e dattiloscritto. Ho una matrice che uso DoCheck e IterableDiffer per ascoltare le modifiche nel mio codice. Quando la matrice viene modificata ricevo le notifiche, ma quando una proprietà all'interno di uno degli oggetti nella matrice cambia, non ricevo la notifica. Ho provato a usare KeyValueDiffer ma non funziona. Penso che forse ho bisogno di usare "_differs.find" in modo diverso. Qualche idea?Rileva modifiche negli oggetti all'interno dell'array in Angular2

@Component({ 
    selector: 'test' 
}) 
@View({ 
    template: ` 
    <div>hello!</div>` 
}) 
export class MyComponent implements DoCheck { 

private _differ: IterableDiffer; 
private _differ2: KeyValueDiffer; 
_myItems: MyItem[]; 
@Input() 
set myItems(value: MyItem[]) { 
    this._myItems = value; 

    if (!this._differ && value) { 
     this._differ = this._iterableDiffers.find([]).create(null); 
    } 
    if (!this._differ2 && value) { 
     this._differ2 = this._differs.find(this._myItems).create(null); 
    } 
} 
get myItems() { 
    return this._myItems; 
} 

constructor(private _iterableDiffers: IterableDiffers, private _differs: KeyValueDiffers, private _myService: MyService) { 
    this.myItems = _myService.getItems(); 
} 

ngDoCheck() { 

    var changes = this._differ.diff(this._myItems); 

    if (changes) { 
     changes.forEachAddedItem((record) => { 
      console.log('added ' + record.item); 
     }); 
     changes.forEachRemovedItem((record) => { 
      console.log('removed ' + record.item); 
     }); 
    } 

    var changes2 = this._differ2.diff(this._myItems); 
    if (changes2) { 
     changes2.forEachChangedItem(
      (record) => { 
        console.log(record.key + "," + record.currentValue); 
       } 
      }); 
    } 
    } 
} 

Non v'è alcun modo di ricevere la notifica sui cambiamenti in una delle proprietà di MyItem

+2

Potresti fornire del codice per mostrare cosa hai provato? Grazie! –

risposta

14

In realtà, è necessario controllare le differenze per ogni oggetto nella lista non sulla lista stessa. KeyValueDiffer deve essere applicato su un oggetto non su un array.

Si potrebbe inizializzare un oggetto che contiene tutti questi KeyValueDiffer casi per gli elementi dell'array:

constructor(private differs: KeyValueDiffers) { 
} 

ngOnInit() { 
    this.objDiffer = {}; 
    this.list.forEach((elt) => { 
    this.objDiffer[elt] = this.differs.find(elt).create(null); 
    }); 
} 

All'interno del ngDoCheck, è necessario poi per scorrere i differ s per verificare che non ci sono cambiamenti (per ogni voce dell'array):

ngDoCheck() { 
    this.list.forEach(elt => { 
    var objDiffer = this.objDiffer[elt]; 
    var objChanges = objDiffer.diff(elt); 
    if (objChanges) { 
     objChanges.forEachChangedItem((elt) => { 
     if (elt.key === 'prop1') { 
      this.doSomethingIfProp1Change(); 
     } 
     }); 
    } 
    }); 
} 

Vedere questo plunkr: http://plnkr.co/edit/JV7xcMhAuupnSdwrd8XB?p=preview

Si noti che ho ignorato il rilevamento modifiche per l'array ... Ma entrambi possono essere eseguiti in parallelo. Inoltre, quando gli elementi vengono aggiunti/rimossi, l'elenco di KeyValueDiffers deve essere aggiornato di conseguenza.

+0

Che cosa fa effettivamente la parte '.create (null)'? – Chrillewoodz

+1

Inizializza il diverso oggetto con null. Quindi il metodo 'diff' può determinare la prima differenza (l'oggetto completo in realtà) ... –

+4

Vuoi mai impostarlo su qualcosa di diverso da null? – Chrillewoodz

Problemi correlati