2016-09-02 1 views
3

Ich habe ein Observable.interval mit 500 ms irgendwo in meinem Komponentenbaum erstellt und abonniert. Die Komponente hat keine Eingabe- oder Ausgabeeigenschaften. Dieses Intervall löst die Änderungserkennung aus, beginnend bei der Wurzelkomponente jedes Mal, wenn es ein Häkchen sendet. Das verursacht viel Overhead in meiner Anwendung, die nicht benötigt wird. Ich finde keine Dokumentation über dieses Verhalten.Angular 2 RC 5 - Observable.interval Trigger Änderungserkennung

Ist es möglich, die durch dieses Observable verursachte Änderungserkennung auszuschalten?

bearbeiten: Hinzufügen von Code

Der folgende Code demonstriert, was ich tun möchte. Ich lege das Intervall außerhalb von Angulars Zone wie von Günter vorgeschlagen, aber jetzt werden Änderungen am Array nicht in der Vorlage veröffentlicht. Gibt es eine Möglichkeit, die Vorlage zu aktualisieren, ohne eine Änderungserkennung auszulösen?

import {NotificationList} from "./NotificationList"; 
import {Notification} from "./Notification"; 
import {Component, OnDestroy, ChangeDetectorRef, NgZone} from "@angular/core"; 
import { Subscription } from 'rxjs/Subscription'; 
import { Observable } from 'rxjs/Observable'; 
import 'rxjs/add/observable/interval'; 

class TimedNotification { 
    notification: Notification; 
    remainingTime: number; 
} 

@Component({ 
    selector: "notifications", 
    template: ` 
     <ul> 
      <li *ngFor="let notification of notifications">notification.message</li> 
     </ul> 
    ` 
}) 
export class NotificationComponent implements OnDestroy { 
    notifications: Array<TimedNotification> = []; 
    private subscription: Subscription; 
    private timer: Subscription = null; 
    private delay: number = 2000; 
    private tickDelay: number = 500; 

    constructor(notificationQueue: NotificationList, private zone: NgZone) { 
     this.subscription = notificationQueue.getObservable().subscribe(notification => this.onNotification(notification)); 
     this.zone.runOutsideAngular(() => {this.timer = Observable.interval(500).subscribe(x => this.onTimer())}); 
    } 

    private onTimer(): void { 
     if(this.notifications.length == 0) { 
      return; 
     } 
     let remainingNotifications: Array<TimedNotification> = []; 
     for(let index in this.notifications) { 
      let timedNotification = this.notifications[index]; 
      timedNotification.remainingTime -= this.tickDelay; 
      if(timedNotification.remainingTime <= 0) { 
       continue; 
      } 
      remainingNotifications.push(timedNotification); 
     } 
     this.notifications = remainingNotifications; 
    } 

    private onNotification(notification: Notification): void { 
     let timedNotification = new TimedNotification(); 
     timedNotification.notification = notification; 
     timedNotification.remainingTime = this.delay; 
     this.notifications.push(timedNotification); 
    } 

    ngOnDestroy(): void { 
     this.subscription.unsubscribe(); 
     if(this.timer !== null) { 
      this.timer.unsubscribe(); 
     } 
    } 
} 

Antwort

0

Sie können es für Komponenten mit ChangeDetectionStrategy.OnPush ausschalten.

Jedes Ereignis bewirkt, dass die Änderungserkennung ausgeführt wird (und setTimeout und alle anderen asynchronen APIs, die von NgZone abgedeckt werden).

Wenn Sie OnPush verwenden, dann werden nur Änderungen an Eingängen und Ereignissen von Observablen, die mit | async signiert sind, geändert.

+0

Ich denke, ich brauche es anders herum. Ich möchte verhindern, dass das Observable eine Änderungserkennung in einer anderen Komponente verursacht. Dieses Intervall ist nur für die Manipulation eines Arrays verantwortlich, es hat keine Verbindung nach außen. – Normalo

+0

Sie können die beobachtbare Zone außerhalb des Angulars ausführen. http://blog.thoughtram.io/angular/2016/02/01/zones-in-angular-2.html#running-code-outside-angulars-zone –

+0

Wow, das ist fast so. Kann ich die Änderungserkennung nur für die Komponente durchführen, in der das Observable erstellt wird? Ich muss die Ansicht aktualisieren, falls das Array aktualisiert wird. – Normalo

Verwandte Themen