Angular 2 RC 5 - Observable.interval触发更改检测

时间:2016-09-02 10:18:57

标签: angular rxjs

我在组件树的某处创建了一个带有500毫秒的Observable.interval并订阅了它。该组件没有输入或输出属性。该间隔在每次发送滴答时从根组件触发更改检测。这导致我的应用程序中的大量开销,这是不需要的。我没有找到任何有关该行为的文档。

是否可以关闭由此Observable引起的更改检测?

修改:添加代码

以下代码演示了我想要做的事情。我按照Günter的建议将区间放在Angular区域之外,但现在对阵列的修改不会在模板中发布。有没有办法在不触发更改检测的情况下更新模板?

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

1 个答案:

答案 0 :(得分:0)

您可以使用ChangeDetectionStrategy.OnPush将组件关闭。

每个事件都会导致更改检测运行(以及setTimeout以及NgZone涵盖的任何其他异步API。

如果您使用OnPush,那么只有来自| async订阅的观察者的输入和事件的更改才会导致更改检测。