2016-03-02 3 views
7

Verwenden von Angular 2 und Typoskript. Ich habe ein Array, das DoCheck und IterableDiffer verwendet, um Änderungen in meinem Code zu hören. Wenn das Array geändert wird, erhalte ich Benachrichtigungen, aber wenn sich eine Eigenschaft in einem der Objekte im Array ändert, werde ich nicht benachrichtigt. Ich habe versucht mit KeyValueDiffer, aber es funktioniert nicht. Ich denke, vielleicht muss ich die "_differs.find" anders verwenden. Irgendwelche Ideen?Erkennen von Änderungen in Objekten innerhalb des Arrays 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); 
       } 
      }); 
    } 
    } 
} 

Es gibt keine Möglichkeit, auf Veränderungen in einer der Eigenschaften von MyItem

+2

Könnten Sie Code bereitstellen, um zu zeigen, was Sie ausprobiert haben? Vielen Dank! –

Antwort

14

In der Tat, um informiert, müssen Sie nicht auf der Liste in der Liste für jedes Objekt Unterschiede überprüfen selbst. KeyValueDiffer muss auf ein Objekt angewendet werden, das nicht auf einem Array liegt.

Sie könnten ein Objekt initialisieren alle diese KeyValueDiffer Instanzen für die Elemente Ihrer Array mit:

constructor(private differs: KeyValueDiffers) { 
} 

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

Im ngDoCheck, müssen Sie dann über die differ s zu durchlaufen dort zu überprüfen, sind Änderungen (für jedes Element des Arrays):

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

dieses plunkr Siehe: http://plnkr.co/edit/JV7xcMhAuupnSdwrd8XB?p=preview

Beachten Sie, dass ich die Änderungserkennung für das Array übersprungen habe ... Beide können jedoch parallel ausgeführt werden. Wenn Elemente hinzugefügt/entfernt werden, sollte außerdem die Liste der KeyValueDiffers entsprechend aktualisiert werden.

+0

Was macht der '.create (null)' Teil eigentlich? – Chrillewoodz

+1

Initialisiert das differ-Objekt mit null. So kann die 'diff' Methode den ersten Unterschied feststellen (das komplette Objekt tatsächlich) ... –

+4

Würdest du das jemals auf etwas anderes als null setzen wollen? – Chrillewoodz

Verwandte Themen