超时更改时,角插值显示不更新 [英] Angular interpolated value display not updating when changed in timeout

查看:75
本文介绍了超时更改时,角插值显示不更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Angular 6.0.1。

Angular 6.0.1.

此问题正在大型应用程序中显现,但我创建了一个简单的组件来尝试查看发生的情况。简单的组件具有一个简单的模板:

This problem is manifesting itself inside a large application, but I created a simple component to try and see what is going on. The simple component has a simple template:

{{myProp}}

在ngOnInit中,设置 this.myProp ='hello'; ,我在屏幕上看到单词 hello 会期望的。到目前为止,一切都很好。

In the ngOnInit, I set this.myProp = 'hello'; and I see the word hello on screen as I would expect. So far so good.

但是,如果我现在尝试在<$ c中更新 myProp 的值$ c> setTimeout ,它永远不会更新UI:

However, if I now try to update the value of myProp in a setTimeout, it never updates the UI:

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

UI中显示的值仍为 hello

The value shown in the UI is still hello.

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

If I inject ChangeDetectorRef in my constructor and call cdr.detectChanges() inside the timer, the UI updates.

这是预期的行为,还是我做错了什么?我不希望为此调用 detectChanges 。我尚未更改该组件的 ChangeDetectorStrategy ,因此它仍然是默认值

Is this expected behavior, or what am I doing wrong? I wouldn't expect to have to call detectChanges for this. I have not changed the ChangeDetectorStrategy for the component so it is still default.

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

Note, that in the "real" app, I'm not updating myProp in a timer, but inside an Observable subscription. The UI is not updating there and that is what has led me to investigate this and end at the timer as the simplest possible reproduction of the problem. As near as I can tell, updating the property value in any type of async manner is not showing the change in the UI.

更新

我认为我对setTimeout的引用使事情感到困惑。我使用它作为调试手段。我没有尝试重新处理此问题,而是在此处发布了一个新问题( Angular插值而不是对订阅进行更新),并提供了更好的解释以及使我感到悲伤的ngRx代码。谢谢。

I think that my reference to setTimeout confused things. I was using that as a means of debugging. Instead of trying to rework this question, I posted a new question here (Angular interpolated value not updating on subscription) with a better explanation and the ngRx code that is causing me grief. Thanks.

更新#2
问题是由具有 ChangeDetectionStrategy 的父组件引起的。 code>设置为 OnPush 。看到我上面提到的问题。

Update #2 The problem was caused by a parent component having its ChangeDetectionStrategy set to OnPush. See the question I referenced above.

谢谢

TTE

推荐答案

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

This is the expected action. The javascript method Window setTimeout is a Window command. This means that it is called outside the main zone.js thread (by which I mean the general change detection contained out of box in an Angular application), which is the expected plan. If you would like to contain your setTimeout() method you need to assign it to a variable contained inside your Angular TypeScript application.

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

This behavior is the most distinct when using a similar method in the same family of functions called from window: the Window setInterval() Method

您可以包含此内容,并且类似 Window 方法。 setTimeout()命令需要附有 ChangeDetectorRef 来检测更改,以便收听已发出的事件。您还可以通过将执行的方法分配给组件变量来插入命令(类似于在组件销毁后如何停止 setInterval()的此答案在这里)。

You are able to contain this, and similar Window methods. The setTimeout() command needs the ChangeDetectorRef attached to it to detect changes in order to listen to Events Emitted. You can also insert commands by assigning the executed method to a component variable (similar to this answer on how to stop setInterval() after a component is destroyed here).

这篇关于超时更改时,角插值显示不更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆