1

角 6.0.1。

这个问题在一个大型应用程序中表现出来,但我创建了一个简单的组件来尝试看看发生了什么。简单组件有一个简单的模板:

{{myProp}}

在 ngOnInit 中,我设置this.myProp = 'hello';并在屏幕上看到了hello这个词,正如我所期望的那样。到目前为止,一切都很好。

但是,如果我现在尝试更新myPropa的值setTimeout,它永远不会更新 UI:

this.myProp = 'hello';
setTimeout(() => {
  this.myProp = 'goodbye';
}, 3000);

UI 中显示的值仍然是hello

如果我注入ChangeDetectorRef我的构造函数并cdr.detectChanges()在计时器内调用,则 UI 会更新。

这是预期的行为,还是我做错了什么?我不希望不得不为此打电话detectChanges。我没有更改ChangeDetectorStrategy组件的,所以它仍然是default.

请注意,在“真实”应用程序中,我不是myProp在计时器中更新,而是在Observable订阅中更新。UI 没有在那里更新,这就是导致我对此进行调查并在计时器处结束的原因,因为它是问题的最简单的可能再现。据我所知,以任何类型的异步方式更新属性值都不会显示 UI 中的更改。

更新

我认为我对 setTimeout 的引用使事情变得混乱。我用它作为调试的手段。我没有尝试重新处理这个问题,而是在此处发布了一个新问题(Angular interpolated value not updated on subscription),提供了更好的解释和让我感到悲伤的 ngRx 代码。

更新 #2 问题是由将其ChangeDetectionStrategy设置为OnPush. 请参阅我上面提到的问题。

4

1 回答 1

1

这是预期的动作。javascript 方法Window setTimeout是一个Window命令。这意味着它是在主zone.js线程之外调用的(我的意思是 Angular 应用程序中包含的常规变更检测),这是预期的计划。如果你想包含你的setTimeout()方法,你需要将它分配给你的 Angular TypeScript 应用程序中包含的一个变量。

当在同一系列函数中使用类似的方法时,这种行为是最明显的windowWindow setInterval() 方法

您可以包含此方法和类似Window方法。setTimeout()命令需要ChangeDetectorRef附加到它以检测更改以侦听 Event Emitted。您还可以通过将执行的方法分配给组件变量来插入命令(类似于 this answer on how to stop setInterval() after a component is destroy here)。

于 2018-08-04T04:15:55.850 回答