Angular 角度插值显示在超时更改时不更新

Angular 角度插值显示在超时更改时不更新,angular,angular-changedetection,Angular,Angular Changedetection,角度6.0.1 这个问题在一个大型应用程序中表现出来,但我创建了一个简单的组件来尝试看看发生了什么。简单组件有一个简单的模板: {{myProp}} 在ngOnInit中,我设置this.myProp='hello'和我在屏幕上看到的单词hello一如我所料。到目前为止还不错 但是,如果我现在尝试在setTimeout中更新myProp的值,它将永远不会更新UI: this.myProp = 'hello'; setTimeout(() => { this.myProp = 'good

角度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

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

更新

我认为我提到的东西很混乱。我用它作为调试的手段。我没有试图重做这个问题,而是在这里发布了一个新问题(),其中有更好的解释和令我悲伤的ngRx代码。谢谢

更新#2 该问题是由父组件将其
ChangeDetectionStrategy
设置为
OnPush
引起的。见我上面提到的问题

谢谢


TTE

这是预期的行动。javascript方法是一个
窗口
命令。这意味着它是在主
zone.js
线程(我指的是角度应用程序中开箱即用的常规更改检测)之外调用的,这是预期的计划。如果希望包含setTimeout()方法,则需要将其分配给Angular TypeScript应用程序中包含的变量

在从
窗口调用的同一系列函数中使用类似方法时,此行为最为明显:


您可以包含此方法以及类似的
窗口
方法。setTimeout()命令需要附加
ChangeDetectorRef
来检测更改,以便侦听发出的事件。您还可以通过将已执行的方法分配给组件变量来插入命令(类似于关于组件销毁后如何停止setInterval()的回答)。

更新异步方法中的属性会更新视图。还有别的事情。请向我们显示调用
setTimeout
的上下文。或者制作一个stackblitz来显示问题。您可以看到,当问题中的代码被执行时,视图被更新。项目中的问题可能是由重新定义了
setTimeout
的库引起的。我认为Angular已经对setTimeout进行了修补,以使其具有区域意识。@TimTheHander他们使其正常工作,因此,如果我没有弄错的话,当您使用箭头函数时,它会正确地将父对象引用为引用对象。一般来说,默认情况下它仍然应该在窗口线程上运行,但如果父线程是订阅函数(如您更新的问题所示),那么它将继续位于应用程序的区域之外(在这种情况下,它将位于rxjs模块的区域内)。最好的方法是避免需要这样的东西,但在极少数必要的情况下添加cdRef不会降低速度。@Timthencher和stackblitz示例演示了由于父级在
窗口
区域中运行,它将如何不更新w/o arrow(并在某种程度上再次向您确认我确实知道我在说什么;D):