2016-11-24 5 views
7

Ich möchte ein Objekt/Array, die von einem Dienst oder von einer Controller-Routine bearbeitet werden können. Ich dachte, dass ein Observable ein Objekt/Array beobachten könnte.Angular2 Uhr Objekt/Array-Änderungen (Angular2 final> = 2.1.1)

Meine Implementierung reagiert nicht auf Änderungen der Elemente:

private data : Observable<Array<any>>; 
    private dataObserver: Observer<Array<any>>; 
    private sub : Subscription; 
    private items: <Array<any>>; 

    ngOnInit() { 
    this.items = itemService.getItems(); 
    this.data = new Observable<Array<any>>(observer =>{ 
     this.dataObserver = observer; 
    }); 
    this.data.subscribe(
     x => console.log('onNext: %s', x), 
     e => console.log('onError: %s', e), 
     () => console.log('onCompleted') 
    ); 
    this.dataObserver.next(this.items); 
    } 


private start(){ 

    //change values of the array in an interval 
    let loop = Observable.interval(250) 
    let i=0; 
    self.sub = loop.subscribe(() => { 
     if(self.items[0]){ 
     self.items[0].id= i; 
     if(i<100) i++; 
     else i=1; 
     } 
    }) 
} 

Die observalbes subsciption auf Änderungen der Artikel Array nicht reagiert. Es löst nur auf seinem nächsten mehtod aus. Auf der anderen Seite .. das ist zu mühsam für eine einfache Uhr Methode.

Was bietet angular-2 uns an, auf Änderungen zu achten, als $ scope. $ Watch did in eckig-1?

Antwort

10

Angular2 stellt IterableDiffer (Array) und KeyValueDiffer (Objekt) bereit, um Informationen über Unterschiede zwischen zwei Überprüfungen zu erhalten.

NgClass ist ein gutes Beispiel https://github.com/angular/angular/blob/14ee75924b6ae770115f7f260d720efa8bfb576a/modules/%40angular/common/src/directives/ng_class.ts#L122

Siehe auch https://angular.io/docs/ts/latest/api/#!?query=differ

Ein Beispiel

// inject a differ implementation 
constructor(differs: KeyValueDiffers) { 
    // store the initial value to compare with 
    this.differ = differs.find({}).create(null); 
} 

@Input() data: any; 

ngDoCheck() { 
    var changes = this.differ.diff(this.data); // check for changes 
    if (changes && this.initialized) { 
    // do something if changes were found 
    } 
} 
+0

Haben Sie ein einfaches Beispiel, wie ein Array/Objekt beobachtet werden könnte? Es ist eine Codezeile in Angular1. Wenn es so kompliziert ist, wie ich es in NgClass sehe, ist es übertrieben. – marcel

+0

Angular2 hat mit Angular1 nicht viel gemeinsam. Sie haben 2 komplette Umschreibungen gemacht, um dorthin zu kommen, wo sie jetzt sind, und das aus einem bestimmten Grund. Angular2 zielt auf maximale Leistung ab. Es gibt Dinge, die besser sind als in Angular1 und andere nicht. Die Dinge, die aus einer Perspektive nicht besser sind, sind normalerweise andere Vorteile zu erhalten. –

+0

Um ein Objekt ein grundlegendes Merkmal zu beobachten. Das bedeutet, dass es in Angular2 nicht möglich ist? Welche Art von Strategie muss ich jetzt in angular2 verfolgen? – marcel

1

Vielen Dank für Ihr Beispiel Gunter.

Ich wähle eine schnelle Lösung basierend auf Ihrer Antwort.

Ich ersetze das OnInit-Handle durch eine DoCheck-Implementierung. Nun, wenn Wertänderung in meinem Dienst extern Sprache genannt wird, wird die Ansicht aktualisiert.

In meinem Fall Beispiel:

import { Component, DoCheck } from "@angular/core"; 
export class LangListUserComponent implements DoCheck { 

    constructor(private _languageService: LanguageService) 
    {} 

    ngDoCheck() { 
    /** Get available lang */ 
    this.oLanguages = this._languageService.getLanguageList(); 
    this.setCurrentLang(this.oLanguages); 
    }; 
} 
2

In dem Import Abschnitt:

import { DoCheck, KeyValueDiffers, KeyValueChangeRecord } from '@angular/core'; 

den 'KeyValueDiffers' Injektor Hinzufügen:

private _differ: any;  

    constructor(private _differs: KeyValueDiffers) { 
      this._differ = _differs.find({}).create(); 
     } 

Schließlich verfolgen Änderungen:

ngDoCheck() { 
     const change = this._differ.diff(this.Your_Object_To_Track); 
     if (change) { 
      change.forEachChangedItem(
       (record: KeyValueChangeRecord<any, any>) => { 
        console.log(record.key + ': ' + record.previousValue + '=>' + record.currentValue) }); 

      change.forEachRemovedItem(    
        (record: KeyValueChangeRecord<any, any>) => { 
         console.log(record.key + ': ' + record.previousValue + '=>' + record.currentValue) }); 

      change.forEachAddedItem((record: KeyValueChangeRecord<any, any>) => { 
         console.log(record.key + ': ' + record.previousValue + '=>' + record.currentValue) }); 
     } 
    }