Angular2 zone.run()vs ChangeDetectorRef.detectChanges() [英] Angular2 zone.run() vs ChangeDetectorRef.detectChanges()

查看:450
本文介绍了Angular2 zone.run()vs ChangeDetectorRef.detectChanges()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我在我的service.ts中有一个函数noificationHandler(),它超出了angular的上下文。
noificationHandler()由第三方调用, noificationHandler()基本上消耗一个数组并发出数组到订阅了他的服务的组件。

Say I have a function noificationHandler() in my service.ts that is outside of angular's context. noificationHandler() is invoked by a third party and noificationHandler() basically consumes an array and emits the array to components which have subscribed to his service.

service.ts

    public mySubject: Subject<any> = new Subject();
    public myObservable = this.mySubject.asObservable();

    constructor() {
       this.registry.subscribe("notification.msg",this.noificationHandler.bind(this));
    }

    noificationHandler(data) {
       this.publishUpdate(data)
    }

    publishUpdate(data) {
       this.mySubject.next(data);
    }

component.ts

constructor(private service: myService) {
    this.service.myObservable.subscribe(list => {
        this.list = list;
    });
}

^^^此时模板未使用新数据更新

^^^ at this point the template is not updated with the new data

由于notification.msg在angular的区域之外,因此不会运行角度
s更改检测当调用此事件(notification.msg)时。

Since the "notification.msg" is outside of angular's zone, angular s change detection is not run when this event("notification.msg") is invoked.

现在有两种方法可以调用更改检测。

Now there are 2 ways to invoke change detection.

1)在angular的zone.run()

1) By wrapping the noificationHandler() inside of angular's zone.run()

 this.registry.subscribe("a2mevent.notification.msg", this.ngZone.run(() => this.noificationHandler.bind(this)));

2)单独要求组件检测更改

2) By individually asking the component to detect changes

constructor(private service: myService, private ref: ChangeDetectorRef) {
    this.service.myObservable.subscribe(list => {
        this.list = list;
        this.ref.detectChanges(); // <==== manually invoking change detection
    });
}

这两个选项都有效!
我的组件结构如下

Both the options work! And my component structure is as follows

A --> root component
B
C
D // my component is here (4 levels of nesting)

问题 -

1)detectChanges()是否仅检测其自身组件的更改,还是会对子组件运行更改检测?

1) Will detectChanges() detect changes only for its own components or will it also run change detection on child components?

2)zone.run()会触发从根到叶子的所有组件的变化检测吗?

2) will zone.run() trigger the change detection of all the components from the root till the leaf?

在zone.run()和detectChanges()中我很好奇性能哪个更好?

Among the zone.run() and detectChanges() I am curious as to which is better in performance?

推荐答案

ApplicationRef.tick (与 setTimeout()相同)和 zone.run()导致整个应用程序的更改检测。此外,在Angular或Angular中添加的事件侦听器(使用视图绑定或 @HostBinding()会导致整个应用程序发生更改检测。

ApplicationRef.tick (same as setTimeout()), and zone.run() cause change detection on the whole application. Also event listeners added within Angular or by Angular (using view bindings or @HostBinding() cause change detection for the whole application.

ChangeDetectorRef.detectChanges 运行特定组件的变更检测(如果适用,则为其后代,例如由于输入绑定)

ChangeDetectorRef.detectChanges runs change detection for a specific component (and its descendants if applicable, for example because of input bindings)

如果在Angular区域外运行的某些代码调用Angular的代码并更改状态,则需要显式调用更改检测,因为Angular无法知道状态发生了变化。

If some code running outside Angular's zone calls into Angular's code and changes the state, then change detection needs to be invoked explicitly because Angular has no way of knowing that the state changed.

如果状态更改是组件的本地(例如组件字段), ChangeDetectorRef.detectChanges ChangeDetectorRef .markforCheck 效率更高。

If the change to the state is local to a component (for example a components field), ChangeDetectorRef.detectChanges or ChangeDetectorRef.markforCheck are more efficient.

如果来自外部的呼叫例如导航到不同的路线,这可能会对许多组件产生影响,并且还不清楚整个路线改变何时完成因为使用它可能会导致异步调用(以及调用回调)。
在这种情况下, zone.run()是更好的选择,因为调用的代码直接和间接调用(如observable和promises的回调)将在Angular中运行zone和Angular将识别它们并自动调用变化检测。

If the call from outside for example navigates to a different route, this can have consequences to a number of components, and it's also not clear when the whole route change is completed because it might cause async calls (and callbacks being called). In this case zone.run() is the better option, because the code directly and indirectly invoked (like callbacks of observables and promises) invoked will run inside Angular's zone and Angular will recognize them and invoke change detection automatically.

这篇关于Angular2 zone.run()vs ChangeDetectorRef.detectChanges()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆