我有一个一般性的角度问题:
为什么角async管使用cdr.markForCheck()而不是cdr.detectChanges()
我所看到的这两种“风格”主要有两个不同之处:
markForCheck()标记要检查到根组件的路径-要更新的内容markForCheck()允许在当前或下一个周期中进行更改检测-定时。我的想法或问题:
async管道中)?为什么不只是当前组件?(detectChanges()) -这涉及到更新的内容markForCheck()中使用ngZone)?为什么不立即检测更改?(detectChanges())这与定时有关async管道改为使用detectChanges(),会发生什么情况? private _updateLatestValue(async: any, value: Object): void {
if (async === this._obj) {
this._latestValue = value;
this._ref.markForCheck();
}
}编辑:
请不要解释每一种方法的作用,因为我在文档中读了很多次,从async的角度来看,我无法理解它。我需要知道的重要部分是,为什么要更新、和定时。
发布于 2020-10-19 08:53:29
为了获得适当的文档,请检查ChangeDetectorRef
detectChanges
检查此视图及其子视图。
如果类已更改,但视图尚未更新,则需要通知角以检测这些更改。
markForCheck
当视图使用OnPush (checkOnce)更改检测策略时,显式地将视图标记为已更改,以便可以再次检查该视图。
仅从文本中您就可以看到,此策略用于组件检测策略已更改为onPush的情况(例如,如果@Input()已更改)。
更新
直接回答你的问题:
它不是检查根,而是检查组件的祖先。

我假设这是一个与性能相关的主题。收集所有需要运行的检查,并在下一个周期中执行它们。
正确,如果不通知角度,那么视图中什么都不会改变。
我想它也能工作,但它不只是检查更改,而是直接执行视图的更新。
发布于 2020-10-19 09:05:47
detectChanges()是:
检查此视图,及其子视图。结合使用detach实现本地更改检测检查。
和
markForCheck()是:
当视图使用OnPush (checkOnce)更改检测策略时,显式地将视图标记为已更改,以便可以再次检查该视图。
因此,detectChanges()立即运行更改检测,而markForCheck()不运行更改检测。
因此,看起来async管道使用markForCheck来避免性能问题。我的意思是在markForcheck()管道中使用async有助于避免不必要的更改检测的运行。
更新:
问题1:
如果没有正在进行的当前更改检测,也没有针对未来CD的ngZone异步触发器,怎么办?
不,视图不会被更新,但是它将标记从当前组件到根组件的所有组件,它们的状态是CheckEnabled。源代码:
export function markParentViewsForCheck(view: ViewData) {
let currView: ViewData|null = view;
while (currView) {
if (currView.def.flags & ViewFlags.OnPush) {
currView.state |= ViewState.ChecksEnabled;
}
currView = currView.viewContainerParent || currView.parent;
}
}问题2:
至于要更新什么,为什么我需要将整个路径标记为根呢?第二个解决方案中的...and (detectChanges)不需要?
请读这个不错的答案,角markForCheck对detectChanges。总之,最好使用markForCheck()方法。
https://stackoverflow.com/questions/64423407
复制相似问题