Angular2 watch object/array changes (Angular2 final >= 2.1.1)

匿名 (未验证) 提交于 2019-12-03 01:48:02

问题:

I'd like to watch an object/array, which ca be edited by a service or by a controllers routine. I thought that an Observable could watch an object/array.

My implementation doesn't react on changes of the items :

  private data : Observable>;   private dataObserver: Observer>;   private sub : Subscription;   private items: >;    ngOnInit() {      this.items = itemService.getItems();      this.data = new Observable>(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

The observalbes subsciption doesn't react on changes of the items array. It only triggers on its next mehtod. On the other hand .. this is too cumbersome for a simple watch method.

What does angular-2 offer us to watch for changes, as $scope.$watch did in angular-1?

回答1:

Angular2 provides IterableDiffer (array) and KeyValueDiffer (object) to get information about differences between two checks.

NgClass is a good example https://github.com/angular/angular/blob/14ee75924b6ae770115f7f260d720efa8bfb576a/modules/%40angular/common/src/directives/ng_class.ts#L122

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

An example

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


回答2:

In the import section:

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

Adding the 'KeyValueDiffers' injector:

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

Finally track changes:

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


回答3:

Thanks for your example Gunter.

I choose a quick solution based on your response.

I replace the OnInit handle by a DoCheck implementation. Now if value change in my service external called Language the view is updated.

In my case example :

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


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!