2016-09-02 17 views
3

コンポーネントツリーのどこかに500msのObservable.intervalを作成して購読しました。このコンポーネントには、入力または出力プロパティはありません。この間隔は、ティックを送信するたびにルートコンポーネントからの変更検出をトリガします。それは私のアプリケーションでは必要のないオーバーヘッドを引き起こします。私はその動作に関するドキュメントを見つけることはできません。角2 RC 5 - Observable.intervalトリガ変更検出

このObservableによって変化検出をオフに切り替えることはできますか?

編集:コード

次のコードを追加すると、私が何をしたいのかを示しています。私はGünterの示唆どおりにAngular's zoneの外側に間隔を置いたが、配列のの変更はテンプレートに公開されていない。変更検出をトリガーせずにテンプレートを更新する方法はありますか?

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

答えて

0

ChangeDetectionStrategy.OnPushを使用してコンポーネントの電源をオフにすることができます。

イベントが発生するたびに変更検出が実行されます(また、setTimeout、およびNgZoneによってカバーされるその他の非同期API)。

OnPushを使用すると、オブザーバブルからの入力とイベントへの変更のみが| asyncであるため、変更検出が行われます。

+0

私はそれが他の方法で必要と思う。 Observableが他のコンポーネントで変更検出を引き起こさないようにしたい。この間隔はアレイの操作にのみ関与し、外部との接続はありません。 – Normalo

+0

ObservableをAngularsゾーン外で実行することができます。 http://blog.thoughtram.io/angular/2016/02/01/zones-in-angular-2.html#running-code-outside-angulars-zone –

+0

うわー、それはほとんどそれです。 Observableが作成されたコンポーネントの変更検出だけを実行できますか?配列が更新された場合にビューを更新する必要があります。 – Normalo

関連する問題