2016-11-24 63 views
7

我想觀察一個對象/數組,它可以由服務或控制器例程編輯。我認爲Observable可以觀看一個對象/數組。Angular2監視對象/數組的變化(Angular2 final> = 2.1.1)

我的執行不會對項目的變化作出反應:

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不上的項目陣列的變化作出反應。它只會在下一個mehtod觸發。另一方面,這對於簡單的手錶方法來說太麻煩了。

angular-2爲我們提供了什麼改變,如$ scope。$ watch在angular-1中做了什麼?

回答

10

Angular2提供IterableDiffer(array)和KeyValueDiffer(object)來獲取有關兩次檢查之間差異的信息。

NgClass就是一個很好的例子https://github.com/angular/angular/blob/14ee75924b6ae770115f7f260d720efa8bfb576a/modules/%40angular/common/src/directives/ng_class.ts#L122

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

一個例子

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

你有一個簡單的例子如何看待數組/對象?它是Angular1中的一行代碼,如果它在NgClass中看起來那麼複雜,那麼它是過度設計的。 – marcel

+0

Angular2與Angular1沒有多少共同之處。他們做了2次完整的重寫,以獲得他們現在的位置,並有原因。 Angular2旨在實現最佳性能。有些事情比Angular1更好,有些則不然。從一個角度來看,情況並不好,通常是爲了獲得其他好處。 –

+0

觀察物體的一個基本特徵。這意味着它不可能在Angular2中?我現在必須遵循什麼樣的策略? – marcel

1

感謝您的例子岡特。

我根據您的回答選擇了一個快速解決方案。

我用DoCheck實現替換OnInit句柄。現在,如果在我的服務外部調用語言更改視圖的值更改。

在我的案例:

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

在進口部:

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

添加 'KeyValueDiffers' 注射器:

private _differ: any;  

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

最後跟蹤變化:

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