我正在努力了解ChangeDetectionStrategy.OnPush
是如何工作的。在许多教程中,人们说当组件具有OnPush
策略时,那么组件只依赖于输入,并且不会发生更改检测,因为组件的子树是传递给子组件的对象具有相同的引用。
从我的测试来看,它是这样工作的。但我想知道为什么对象的修改仍然反映在父组件中,即使它们也有OnPush
策略?看起来组件正在调用类似markForCheck的东西,并且父组件被标记为运行更改检测。
但为什么呢?OnPush
不是应该用来告诉这个组件只依赖于父组件的输入属性吗?如果父组件也是OnPush
组件,为什么要对其进行更改检测?
这是我的示例应用程序。当我单击changeDataImmutable时,子组件中的所有数据都会更改,因为创建了新对象。但是,当我单击changeDataMutable时,子组件不会更改。但是,当我单击modifyX或modifyY,它会突变一些深度嵌套的属性时,这些更改仍然反映在父组件(组件1)中。为什么?
但我想知道为什么对象的修改仍然反映在父组件,即使它们也有OnPush策略?
这是因为您使用了事件,尤其是click
:
<button (click)="changeDataImmutable()">changeDataImmutable</button>
所有本机事件都标记当前组件及其所有祖先进行一次检查。因此,当Angular运行Component1
的变化检测时,其状态为checksEnabled
,因此执行DOM更新。
有关更改检测的最全面解释,请阅读:
- 关于Angular中的变化检测,您需要了解的一切
要了解有关markForCheck
的更多信息,请参阅以下答案并阅读本文:
- 如果您认为
ngDoCheck
表示正在检查您的组件—阅读这篇文章