gpt4 book ai didi

棱 Angular 分明。为什么调用 markForCheck() 结果查看更新

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

到处都说 markForCheck 只是将当前组件 View 和所有父组件(直到根组件)标记为脏。所以下次 DetectChanges 执行时它会更新 View 。
从这一点上我有两个问题。两者都在组件具有 changeDetection: ChangeDetectionStrategy.OnPush 的上下文中

1) 如果 'async pipe' 只调用 markForCheck ( source code ),为什么会更新 View ?

2) 如果我尝试在某个异步进程中调用 markForCheck, View 也会更新。

演示:stackblitz

你能帮我理解在这些过程中发生了什么以及为什么 View 实际更新了吗?我期待有人在 1) 和 2) 之后调用 DetectChanges 方法,但是谁...

最佳答案

在@David 的帮助下,我找到了答案。

首先,RxJs 无论如何都没有用 zone 包裹,但是原生异步函数是(如 setTimer/Itervalfetch api、 XHRDOM events )。由于 RxJ 的 timer/delay(...) 操作符使用本地异步函数,这导致它们也在区域上下文中处理。

这就是我们在 Rx 中时 Callstack 的样子 tap运算符(operator)

enter image description here
您可以看到 Rx 部分位于 Angular/Zone 1 之后。

Angular 轮到他使用区域调用 tick() 执行异步回调时的函数。 Tick方法从根组件下降并查找标记以检查 View 。

我在tick函数中放置了断点,它在我们的回调执行后被调用

enter image description here

那么当我们使用 async pipe 时,在第一种情况下会发生什么?在模板上。

  • 异步回调由异步管道操作符处理,并且调用 markForCheck() 函数
  • 正如我们所知,markForCheck 将当前和父 View 标记为 RootComponent 以供检查
  • 完成第一步的回调后,tick()叫做。最后将检查 View 并更新它

  • 第二种情况几乎相同,当我们调用 markForCheck 时RxJs 运算符内部。我们做同样的事情 async pipe确实如此,并且因为我们的回调也被 zone 包裹,所以我们在回调完成后执行相同的过程。

    如果您不会在异步回调中调用 markForCheck,而是调用 tick 函数,则不会进行任何更新。
    值得一提的是,如果您调用detectChanges(),即使没有调用markForCheck 函数,也会完成更新。
    这是 stackblitz 上的示例
    这是由于 ChangeDetectorRef 中的 detechChanges 忽略了 markForCheck 标志,并对 Component 及其所有子项进行了更改检测。
    更多细节在此 article

    This method runs change detection for the current component view regardless of its state

    关于棱 Angular 分明。为什么调用 markForCheck() 结果查看更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62005104/

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