2016-03-02 17 views
7

Używanie Angular 2 i maszynopisu. Mam tablicę, w której używam DoCheck i IterableDiffer, aby słuchać zmian w moim kodzie. Gdy tablica zostanie zmieniona, otrzymuję powiadomienia, ale gdy właściwość wewnątrz jednego z obiektów w tablicy się zmieni, nie otrzymam powiadomienia. Próbowałem użyć KeyValueDiffer, ale nie działa. Myślę, że może potrzebuję użyć "_differs.find" inaczej. Jakieś pomysły?Wykrywanie zmian w obiektach wewnątrz macierzy w 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); 
       } 
      }); 
    } 
    } 
} 

Nie ma sposobu, aby otrzymywać powiadomienia o zmianach w jednej z właściwości MyItem

+2

Czy możesz podać kod, aby pokazać, co próbowałeś? Dzięki! –

Odpowiedz

14

w rzeczywistości, trzeba sprawdzić różnice dla każdego obiektu na liście nie na samej liście. KeyValueDiffer musi być zastosowany do obiektu spoza tablicy.

Można zainicjować obiekt zawierający wszystkie te KeyValueDiffer instancji dla elementów macierzy:

constructor(private differs: KeyValueDiffers) { 
} 

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

W ngDoCheck, trzeba następnie iteracyjne nad differ s do sprawdzenia są zmiany (dla każdej pozycji tablicy):

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(); 
     } 
     }); 
    } 
    }); 
} 

Zobacz ten plunkr: http://plnkr.co/edit/JV7xcMhAuupnSdwrd8XB?p=preview

Zauważ, że pominąłem wykrywanie zmian dla tablicy ... Ale oba mogą być wykonywane równolegle. Ponadto, gdy elementy są dodawane/usuwane, lista KeyValueDiffers powinna zostać odpowiednio zaktualizowana.

+0

Co właściwie robi partia '.create (null)'? – Chrillewoodz

+1

Inicjuje obiekt różniący się wartością NULL. Tak więc metoda 'diff' może określić pierwszą różnicę (faktycznie cały obiekt) ... –

+4

Czy kiedykolwiek chciałbyś ustawić to na coś innego niż zero? – Chrillewoodz

Powiązane problemy