【发布时间】:2019-01-11 21:51:15
【问题描述】:
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。
请注意,在“真实”应用程序中,我不是在计时器中更新myProp,而是在Observable 订阅中。 UI 没有在那里更新,这就是导致我对此进行调查并在计时器处结束的原因,因为它是问题的最简单的可能再现。据我所知,以任何类型的异步方式更新属性值都不会显示 UI 中的更改。
更新
我认为我对 setTimeout 的引用使事情变得混乱。我用它作为调试的手段。我没有尝试重新处理这个问题,而是在此处 (Angular interpolated value not updating on subscription) 发布了一个新问题,其中提供了更好的解释以及让我感到悲伤的 ngRx 代码。
更新 #2
该问题是由将其ChangeDetectionStrategy 设置为OnPush 的父组件引起的。请参阅我上面提到的问题。
【问题讨论】:
-
在异步方法中更新属性确实会更新视图。其他事情正在发生。请向我们展示调用
setTimeout的上下文。或者制作一个显示问题的堆栈闪电战。 -
您可以在this stackblitz 中看到,当您的问题中的代码执行时,视图会更新。您项目中的问题可能是由重新定义
setTimeout的库引起的。
标签: angular angular-changedetection