2016-11-24 5 views
7

Je voudrais regarder un objet/tableau, qui peut être édité par un service ou par une routine de contrôleurs. Je pensais qu'un Observable pouvait regarder un objet/tableau.Angular2 surveille les changements d'objet/tableau (Angular2 final> = 2.1.1)

Ma mise en œuvre ne réagit pas sur les modifications des articles:

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

Le observalbes ne réagit pas Souscription sur les changements du tableau d'éléments. Il se déclenche seulement sur son prochain méhtod. D'un autre côté ... c'est trop lourd pour une simple méthode de surveillance.

Qu'est-ce que angular-2 nous offre de surveiller les changements, comme $ scope. $ Watch l'a fait dans angular-1?

Répondre

10

Angular2 fournit IterableDiffer (tableau) et KeyValueDiffer (objet) pour obtenir des informations sur les différences entre deux vérifications.

NgClass est un bon exemple https://github.com/angular/angular/blob/14ee75924b6ae770115f7f260d720efa8bfb576a/modules/%40angular/common/src/directives/ng_class.ts#L122

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

Un exemple

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

Avez-vous un exemple simple comment un tableau/objet pourrait être regardé? C'est une ligne de code dans Angular1, si c'est compliqué comme je le vois dans NgClass, il est sur-conçu. – marcel

+0

Angular2 n'a pas beaucoup en commun avec Angular1. Ils ont fait 2 réécritures complètes pour arriver où ils sont maintenant, et pour une raison. Angular2 vise une performance maximale. Il y a des choses qui sont meilleures que dans Angular1 et d'autres qui ne le sont pas. Les choses qui ne sont pas meilleures d'un point de vue, ont généralement d'autres avantages. –

+0

Pour regarder un objet une caractéristique fondamentale. Cela signifie que ce n'est pas possible dans Angular2? Quel genre de stratégie dois-je suivre dans angular2 maintenant? – marcel

1

Merci pour votre exemple Gunter. Je choisis une solution rapide en fonction de votre réponse.

Je remplace le handle OnInit par une implémentation DoCheck. Maintenant, si la valeur change dans mon service externe appelé Language, la vue est mise à jour.

Dans mon exemple de cas:

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

Dans la section d'importation:

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

Ajout de l'injecteur 'KeyValueDiffers':

private _differ: any;  

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

suivre enfin les changements:

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