2016-11-24 15 views
7

Chciałbym obejrzeć obiekt/tablicę, które będą edytowane przez usługę lub procedurę kontrolera. Myślałem, że obserwowalne może oglądać obiekt/tablicę.Angular2 obserwuje zmiany obiektu/macierzy (Angular2 final> = 2.1.1)

Moja implementacja nie reagują na zmiany pozycji:

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

observalbes subsciption nie reaguje na zmiany układu elementów. Wyzwala tylko na następnej mecie. Z drugiej strony jest to zbyt kłopotliwe w przypadku prostej metody oglądania.

Co oferuje nam kątomierz 2 do oglądania zmian, ponieważ $ scope. $ Watch zrobił w kanciastym-1?

Odpowiedz

10

Angular2 dostarcza IterableDiffer (tablica) i KeyValueDiffer (obiekt), aby uzyskać informacje o różnicach między dwiema kontrolami.

NgClass jest dobrym przykładem https://github.com/angular/angular/blob/14ee75924b6ae770115f7f260d720efa8bfb576a/modules/%40angular/common/src/directives/ng_class.ts#L122

Zobacz również https://angular.io/docs/ts/latest/api/#!?query=differ

Przykładem

// 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

Czy masz prosty przykład na to, jak można oglądać tablicę/obiekt? Jest to jedna linijka kodu w Angular1, jeśli jest to tak skomplikowane, jak widzę w NgClass, to jest przepracowane. – marcel

+0

Angular2 ma niewiele wspólnego z Angular1. Zrobili 2 pełne przepisanie, aby dostać się tam, gdzie teraz są, i nie bez powodu. Angular2 dąży do maksymalnej wydajności. Są rzeczy, które są lepsze niż w Angular1, a inne nie. Rzeczy, które nie są lepsze z jednej perspektywy, zwykle przynoszą inne korzyści. –

+0

Obserwowanie obiektu jako podstawowej funkcji. To znaczy, że w Angular2 nie jest to możliwe? Jaką strategię mam teraz zastosować w angular2? – marcel

1

Dzięki za przykład Gunter.

Wybieram szybkie rozwiązanie na podstawie Twojej odpowiedzi.

Wymieniam uchwyt OnInit przez implementację DoCheck. Teraz, jeśli zmieni się wartość w moim serwisie zewnętrznym wywołanym językiem, widok zostanie zaktualizowany.

W moim przykładzie obudowy:

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

W sekcji Import:

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

dodanie wtryskiwacz 'KeyValueDiffers':

private _differ: any;  

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

Wreszcie śledzić zmiany:

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