Angular 6.0.1 .
这个问题在一个大型应用程序中体现出来,但我创建了一个简单的组件来尝试查看正在发生的事情 . 简单组件有一个简单的模板:
{{myProp}}
在ngOnInit中,我设置了 this.myProp = 'hello';
,我在屏幕上看到了 hello 这个词,正如我所料 . 到现在为止还挺好 .
但是,如果我现在尝试在 setTimeout
中更新 myProp
的值,它永远不会更新UI:
this.myProp = 'hello';
setTimeout(() => {
this.myProp = 'goodbye';
}, 3000);
UI中显示的值仍为 hello .
如果我在构造函数中注入 ChangeDetectorRef
并在计时器内调用 cdr.detectChanges()
,则UI会更新 .
这是预期的行为,还是我做错了什么?我不希望为此致电 detectChanges
. 我没有更改组件的 ChangeDetectorStrategy
,所以它仍然是 default
.
请注意,在"real"应用程序中,我不是在计时器中更新 myProp
,而是在 Observable
订阅中更新 . 用户界面没有在那里进行更新,这就是让我对此进行调查并以计时器结束最简单的问题再现的原因 . 据我所知,以任何类型的异步方式更新属性值都不会显示UI中的更改 .
Update
我认为我对setTimeout的引用让人感到困惑 . 我正在使用它作为调试手段 . 我没有尝试重写这个问题,而是在这里发布了一个新问题(Angular interpolated value not updating on subscription),其中有一个更好的解释和导致我悲伤的ngRx代码 . 谢谢 .
Update #2 问题是由父组件将 ChangeDetectionStrategy
设置为 OnPush
引起的 . 请参阅上面提到的问题 .
谢谢,
TTE
1 回答
这是预期的行动 . javascript方法Window setTimeout是
Window
命令 . 这意味着它在主zone.js
线程之外被调用(我指的是Angular应用程序中包含的常规更改检测),这是预期的计划 . 如果要包含 setTimeout() 方法,则需要将其分配给Angular TypeScript应用程序中包含的变量 .当从
window
调用的同一系列函数中使用类似方法时,此行为最明显:the Window setInterval() Method您可以包含此类和类似的
Window
方法 . setTimeout() 命令需要附加的ChangeDetectorRef
来检测更改,以便侦听发出的事件 . 您还可以通过将执行的方法分配给组件变量来插入命令(类似于关于如何在组件被销毁后停止 setInterval() 的答案here) .