当前位置: 首页 > 知识库问答 >
问题:

Angular2 zone.run() vs ChangeDetectorRef.detectChanges()

江子石
2023-03-14

假设我的服务中有一个函数noificationHandler()。ts超出了angle的上下文noificationHandler()由第三方调用,并且基本上使用数组并将数组发送给订阅了其服务的组件。

服务.

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

组件.ts

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

^^^此时,模板没有用新数据更新

由于< code >“notification . msg”在angular的区域之外,因此调用此事件< code >(“notification . msg”)时,angular的变化检测不会运行。

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

1) 通过将noificationHandler()包装在angular的zone.run()内

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

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

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

两个选项都可以!我的组件结构如下

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

问题-

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

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

在 zone.run() 和检测更改() 中,我很好奇哪个性能更好?

共有2个答案

江宏深
2023-03-14

两者完全不同。

NgZone是一个为应用程序提供区域的库,因此可以将实例运行到多个作用域中。

ChangeDetection总是像

此外,Application ationRef类似于ChangeDetector;不同之处在于它将检测从根组件到最后一个子组件的更改。

查内检测和NgZone是最好的组合,以避免不必要的更改检测

陈成济
2023-03-14

应用程序和应用程序重新标记(与设置超时 ()相同)和区域运行() 导致对整个应用程序进行更改检测。此外,在 Angular 中或由 Angular 添加的事件侦听器(使用视图绑定或 @HostBinding() 会导致整个应用程序的更改检测。

更改检测器重新引用更改对特定组件(及其后代,如果适用,例如由于输入绑定)运行更改检测

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

如果状态更改是组件的本地更改(例如组件字段),ChangeDetectorRef。detectChangesChangeDetectorRef。markforCheck更有效。

例如,如果来自外部的呼叫导航到不同的路由,则可能会对许多组件产生影响,并且整个html" target="_blank">路由更改何时完成也不清楚,因为它可能会导致异步调用(和调用回调)。在这种情况下,zone.run() 是更好的选择,因为直接和间接调用的代码(如可观察量和promise的回调)将在Angular的区域内运行,Angular将识别它们并自动调用更改检测。

 类似资料:

相关问答

相关文章

相关阅读