Angular 对树中的父级执行不必要的更改检测

问题描述 投票:0回答:1

我正在创建一个组件,可以在给定的静态位置或相对于组件的位置策略上使用给定的模板渲染覆盖。

层次结构如下所示:

enter image description here

渲染叠加层的组件位于

AppComponent
的底部,它基本上是叠加层对象的列表,并渲染该列表。

当我将新元素插入到叠加数组中时,无论从何处插入,它都会触发对

AppComponent
的更改检测,即使它不需要触发任何检测。

如果我在

AppComponent
上使用OnPush,它会阻止它,但随后我需要自己在树上管理更改检测,但我不想这样做。

对于演示,我创建了一个名为

TestComponent
的 1 个页面的 stackblitz,它实现了
DoCheck
以查看是否触发了更改检测,并且在
OverlaysComponent
中,我添加了一个 setTimeout,它在
NgZone
的角度之外运行,并添加了使用
NgZone#run
将新元素添加到角度内的数组中。

当我将元素添加到列表中时,我从

TestComponent
获取 DoCheck 控制台日志。即使我在 Angular 之外运行它并调用
cdr.detectChanges
,它也会触发相同的
DoCheck
事件。

Stackblitz 链接在此

事情应该是这样吗?

https://angular-live-compiler-jk8dsa.stackblitz.io

尝试过有角度的

8.2.14
13.3.9

我想澄清一下,如果这就是它的工作原理的话,为什么这对我如此重要。我的项目规模很大,编写时适当地防止了内存泄漏和不必要的渲染。当我有很多组件并且组件树变得非常大时,在我的情况下,每组更改检测周期都会使堆增加超过 10mb。

因此,每次我打开或关闭覆盖层时,我都会触发更改检测

angular angular-changedetection
1个回答
0
投票

让我们总结一下已经说过的话以及回答问题的内容:

ngDoCheck 始终被调用,不能用于检查组件是否检测到更改。使用 Angular DevTools 查看树中的更新。 – 谢尔盖 5 月 19 日 10:48

你的AppComponent不是OnPush。根据经验,所有组件都应标有它。 – 谢尔盖 5月19日 10:50

要通过信号消除不必要的变更检测,需要使用 OnPush 变更检测策略 – Tibère B. 5 月 19 日 12:38

将您的应用程序变成 OnPush 它会带来比您想要实现的更多的好处。 OnPush 是标准 *– Sergey 5 月 19 日 18:43

异步操作始终会导致更改检测,除非它们在区域外运行。您可以使用 ChangeDetectorRef 上的分离从更改检测树中分离组件。 – 谢尔盖 5 月 19 日 18:46

© www.soinside.com 2019 - 2024. All rights reserved.