gpt4 book ai didi

angular - 尽管有 OnPush 策略,为什么 Angular 会在 DOM 事件的父组件上触发 ChangeDetection?

转载 作者:行者123 更新时间:2023-12-05 04:30:59 26 4
gpt4 key购买 nike

技巧问题我还没有在文档中找到任何答案。

AppRef.tick() 被调用时(主要是通过 NgZone 补丁),一个变化检测周期被触发。它从树顶部的根组件到底部经过:

  • 具有默认策略的每个组件
  • 每个由 markForCheck 标记的组件(及其祖先)

并跳过未标记的 OnPush 组件。

但是为什么当一个事件被一个组件触发时,它的所有祖先也会被检查?就像调用了 markForCheck 一样。

我期待与调用 AppRef.tick 时相同的行为。我不明白为什么要检查 OnPush parent 。在 this demo 上可以很好地看到这种行为.

另请参阅 working illustration on stackblitz

最佳答案

也许你对OnPush的误解和我刚开始学习变化检测的时候一样:)。重点是:OnPush 策略不会改变任何关于触发 CD 周期的事件。这只是taken care of by zone.js by patching browser APIs . (除非手动触发 CD。)zone.js 不关心组件和 ChangeDetectionStrategies。并且 CD 总是从根目录开始为 @Chris Hamilton解释。

ChangeDetectionStrategy.Default 和 OnPush 的区别仅在于组件将在 CD 周期中实际被检查。

所以你原帖中的句子应该是:“已知 OnPush 策略仅在以下情况下标记要检查的组件”。

下面是我使用 Angular DevTools 的分析器观察到的示例.我在OnPush组件的ngOnInit中放了一个setTimeout(() => {}, 6000),它触发了一个CD循环(来源是“setTimeout”),但是并没有引起组件本身进行检查。

enter image description here

关于手动触发的detectChanges()、tick()和markForCheck()的区别:

  • ChangeDetectorReference.detectChanges() 通过尊重子组件的 CD 策略在此组件及其子组件上触发 CD
  • ApplicationRef.tick() 通过遵守 CD 策略为整个应用程序触发 CD
  • ChangeDetectorReference.markForCheck() 不会触发 CD,但会将所有 OnPush parents 标记为在当前或下一个 CD 周期中检查一次

(解释得很好 here )

===编辑:更新问题的答案===

如果浏览器事件监听器在 OnPush 组件中被触发,这将导致 OnPush 组件被标记为检查。此外,它还会触发从组件根部开始的更改检测。

如果我理解正确的话,你的问题是:为什么 OnPush 组件的所有父组件也必须标记为检查?

回答:如果一个OnPush组件没有被标记为check,那么不仅这个组件会被跳过,这个组件下面的整个子树也会被跳过。这意味着,如果事件处理程序被触发的组件有一个带有 OnPush 的父组件不会被检查,它本身也不会被检查。或者,反过来说,如果要检查一个组件,则还必须检查它的所有祖先。

关于angular - 尽管有 OnPush 策略,为什么 Angular 会在 DOM 事件的父组件上触发 ChangeDetection?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71945490/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com