角度变化检测问题。为什么这个黑客有效?

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

我正在使用

Angular 17
,并且有一个相当复杂的应用程序,其中包含多个组件、一些第三方服务和一个 Google 地图实例。 我的 html 中有很多绑定属性,一些属性使用
@for()
绑定到变量,一些简单地绑定到
let
的值,其他属性使用
AsyncPipe
绑定到可观察值。

对于没有包含任何示例代码,我深表歉意。主要问题之一是,每当我尝试建立一个简单的示例时,它似乎都工作正常。我至少对如何设置数据绑定有一个基本的了解,所以我只能假设我在实际构建中所做的一些事情已经搞砸了这个过程。

从一开始我就发现,在某些情况下 - 通常是带有

label
disabled
值绑定的按钮,视图不会根据绑定数据进行更新,我不得不使用大量
detectChanges()
让一切都保持甜蜜。

今天,即使这样也停止工作,只有当我触发了附加侦听器的内容时,我的视图才会更新。 这导致我进行了一次黑客攻击,似乎已经解决了我所有的问题。我只是将一个

click
侦听器附加到整个应用程序的最外层容器。它什么也没做,只是一个空函数,但现在我的大部分问题都消失了。

那么这里发生了什么? 为什么在最高级别触发空侦听器会比调用

detectChanges()
更成功地强制进行更改检测?

如果您能就为什么变化检测没有像我期望的那样发挥作用提出建议,那就加分了。在复杂的情况下我可能会做什么可能会破坏它?

angular
1个回答
0
投票

我要检查的第一件事是异步操作结果的命令式赋值。

例如 ngOnInit 中的订阅,其中 rxjs 管道内部有异步操作 - 然后订阅块会将结果正确分配给局部变量(绑定在模板中),但您不会看到它,因为更改检测没有认为某件事发生了。然后,您移动鼠标或单击某处或类似位置,更改检测将启动,并使用结果值更新模板。这里一个糟糕的解决方案是在订阅中使用信号。一个好的解决方案是直接使用异步管道而不是订阅块在模板中使用 rxjs 结果。

同样的逻辑也适用于例如setTimeout 和所有其他异步处理程序/承诺,您将结果分配给局部变量,并想知道为什么在其他事情发生之前什么都看不到。

在我们的客户端中,每个组件都是 OnPush 且 rxjs 被广泛使用,并且没有使用单个 ChangeDetectorRef 因此它可以工作。如果没有代码示例,很难给出准确的建议。

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