假设我的服务中有一个函数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() 和检测更改() 中,我很好奇哪个性能更好?
两者完全不同。
NgZone是一个为应用程序提供区域的库,因此可以将实例运行到多个作用域中。
ChangeDetection总是像
此外,Application ationRef
类似于ChangeDetector;不同之处在于它将检测从根组件到最后一个子组件的更改。
查内检测和NgZone是最好的组合,以避免不必要的更改检测
应用程序和应用程序重新标记
(与设置超时 ()相同)
和区域运行()
导致对整个应用程序进行更改检测。此外,在 Angular 中或由 Angular 添加的事件侦听器(使用视图绑定或 @HostBinding()
会导致整个应用程序的更改检测。
更改检测器重新引用更改
对特定组件(及其后代,如果适用,例如由于输入绑定)运行更改检测
如果在Angular的区域之外运行的某些代码调用Angular的代码并更改状态,则需要显式调用更改检测,因为Angular无法知道状态已更改。
如果状态更改是组件的本地更改(例如组件字段),ChangeDetectorRef。detectChanges
或ChangeDetectorRef。markforCheck
更有效。
例如,如果来自外部的呼叫导航到不同的路由,则可能会对许多组件产生影响,并且整个html" target="_blank">路由更改何时完成也不清楚,因为它可能会导致异步调用(和调用回调)。在这种情况下,zone.run()
是更好的选择,因为直接和间接调用的代码(如可观察量和promise的回调)将在Angular的区域内运行,Angular将识别它们并自动调用更改检测。