【问题标题】:Angular interpolated value display not updating when changed in timeout超时更改时角度插值显示不更新
【发布时间】: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


【解决方案1】:

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

在从window 调用的同一系列函数中使用类似方法时,这种行为最为明显:the Window setInterval() Method

您可以包含这个以及类似的Window 方法。 setTimeout() 命令需要附加ChangeDetectorRef 来检测更改,以便监听发出的事件。您还可以通过将执行的方法分配给组件变量来插入命令(类似于this answer on how to stop setInterval() after a component is destroy here)。

【讨论】:

  • 我认为 Angular 已经对 setTimeout 进行了猴子补丁以使其具有区域感知能力。
  • @TimTheEnchanter 他们使它起作用,以便当您使用箭头函数时,如果我没记错的话,它会正确地将父对象称为引用对象。一般来说,默认情况下它仍应在 Window 线程上运行,但如果父级是订阅函数(作为您更新的问题),那么它将继续在您的应用程序区域之外(在这种情况下,它将在 rxjs模块的区域)。最好的方法是避免需要这样的东西,但是在稀有必要的情况下添加 cdRef 根本不会减慢变薄的速度。
  • @TimTheEnchanter 和 stackblitz 示例展示了由于父级在Window 区域中运行,它不会更新的无箭头(并再次确认我确实知道我是什么)谈论;D):stackblitz.com/edit/angular-djwgom
猜你喜欢
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-12
  • 1970-01-01
  • 2021-03-26
相关资源
最近更新 更多