Javascript Angular2,在settimeout变量更改后视图不更新

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34491871/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 16:25:35  来源:igfitidea点击:

Angular2, view not updating after variable changes in settimeout

javascripttypescriptangularangular2-template

提问by Jurgen Welschen

I am trying to setup my first angular2 application as an experiment and am using the latest beta release.

我正在尝试将我的第一个 angular2 应用程序设置为实验,并且正在使用最新的 beta 版本。

I am facing a weird issue where the variable i am using in my view is not being updated after setting a timeout.

我面临一个奇怪的问题,我在视图中使用的变量在设置超时后没有更新。

@Component({
    selector: "my-app",
    bindings: []
})

@View({
    templateUrl: "templates/main.component.html",
    styleUrls: ['styles/out/components/main.component.css']
})

export class MainComponent {

    public test2 = "initial text";

    constructor() {
        setTimeout(() => {
            this.test2 = "updated text"; 
        }, 500);

    }
}

As you can see i have a variable named test2 and in the constructor i set a timeout of 500 ms where i am updating the value to "updated text".

如您所见,我有一个名为 test2 的变量,并且在构造函数中我将超时设置为 500 毫秒,我将值更新为“更新文本”。

Then in my view main.component.html i simply use:

然后在我看来 main.component.html 我只是使用:

{{ test2 }}

But the value will never be set to "updated text" and stays on "initial text" forever even though the update part is being hit. If i follow the angular2 tutorial they dont really give me an answer to this solution. Was wondering if anyone would have an idea of what i am missing here.

但是该值永远不会被设置为“更新文本”并且永远保持在“初始文本”上,即使更新部分被命中。如果我遵循 angular2 教程,他们并没有真正给我这个解决方案的答案。想知道是否有人会知道我在这里缺少什么。

edit: my full code i am using including the bootstrap and html etc

编辑:我正在使用的完整代码,包括引导程序和 html 等

<html>
<head>
    <title>Angular 2</title>
    <script src="/node_modules/systemjs/dist/system.src.js"></script>
    <script src="/node_modules/reflect-metadata/reflect.js"></script>
    <script src="/node_modules/angular2/bundles/angular2.dev.js"></script>

    <script src="/node_modules/q/q.js"></script>
    <script src="/node_modules/jquery/dist/jquery.js"></script>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <script src="/bower_components/breeze-client/breeze.debug.js"></script>
    <script src="/bower_components/datajs/datajs.js"></script>
    <script src="/bower_components/bootstrap-less/js/collapse.js"></script>
    <script src="/bower_components/bootstrap-less/js/modal.js"></script>

    <script src="/bower_components/signalr/jquery.signalR.js"></script>
    <script src="http://localhost:64371/signalr/js"></script>

    <link href="styles/out/main.css" type="text/css" rel="stylesheet"  />
    <script>
        System.config({
            map: {
                rxjs: '/node_modules/rxjs' // added this map section
            },
            packages: {'scripts/out': {defaultExtension: 'js'}, 'rxjs': {defaultExtension: 'js'}}
        });

        System.import('scripts/out/main');

    </script>
</head>
<body>
    <my-app>loading...</my-app>
</body>
</html>

main.ts with the bootstrap:

带有引导程序的 main.ts:

import {Component} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser'
import {COMMON_DIRECTIVES} from './constants';
import {MainComponent} from './components/main.component'
bootstrap(MainComponent);

main-component.html

主组件.html

{{ test2 }}

采纳答案by Thierry Templier

As Vlado said, it should work ;-)

正如 Vlado 所说,它应该可以工作 ;-)

I think that the angular2-polyfills.jslibrary should be included into your page. I can't see it. This file is essentially a mashup of zone.js and reflect-metadata. Zones take part of the detection of updates.

我认为该angular2-polyfills.js库应该包含在您的页面中。我看不到。这个文件本质上是 zone.js 和反射元数据的混搭。区域参与检测更新。

You could have a look at this video where Bryan Ford explains what it is: https://www.youtube.com/watch?v=3IqtmUscE_U.

你可以看看这个视频,布莱恩福特解释了它是什么:https: //www.youtube.com/watch?v=3IqtmUscE_U

Hope it helps you, Thierry

希望对你有帮助,蒂埃里

回答by Vlado Tesanovic

That should work. Do you have any other errors in console?

那应该工作。您在控制台中还有其他错误吗?

@Component({
 selector: 'my-app',
 template: `<h1>Hello {{title}}</h1>`
})
export class App {
 public title: string = "World";
 constructor() {
   setTimeout(() => {
    this.title = "Brave New World"
   }, 1000);)
 }
}

Look at this Plunker: http://plnkr.co/edit/XaL4GoqFd9aisOYIhuXq?p=preview

看看这个 Plunker:http://plnkr.co/edit/XaL4GoqFd9aisOYIhuXq?p=preview

回答by Ben

I had a very similar problem to the OP where even in a basic Angular2 setup changes to bound properties would not be reflected by the view automatically. At this point in time we're using Angular2 2.0.0-rc.6. There was no error message.

我有一个与 OP 非常相似的问题,即使在基本的 Angular2 设置中,对绑定属性的更改也不会被视图自动反映。此时我们正在使用 Angular2 2.0.0-rc.6。没有错误信息。

In the end I found the culprit to be a reference to es6-promise.js, which was 'required' by a third party component we use. Somehow this interfered with the core-js reference we are using which is suggested with rc6 in some of the Angular2 tutorials.

最后我发现罪魁祸首是对 es6-promise.js 的引用,这是我们使用的第三方组件“需要”的。不知何故,这干扰了我们正在使用的 core-js 参考,在一些 Angular2 教程中建议使用 rc6。

As soon as I got rid of the es6-promise.js reference, the view updated correctly after changing a property on my component (via Promise or timeout).

一旦我摆脱了 es6-promise.js 引用,视图就会在更改组件上的属性(通过 Promise 或超时)后正确更新。

Hope this helps somebody some day.

希望有一天这对某人有所帮助。

回答by artemisian

In Angular2 (~2.1.2) another way to make it work is through the ChangeDetectorRef class. The original question code would look like this:

在 Angular2 (~2.1.2) 中,另一种使其工作的方法是通过 ChangeDetectorRef 类。原始问题代码如下所示:

import { 
  ChangeDetectorRef
  // ... other imports here
} from '@angular/core';

 @Component({
    selector: "my-app",
    bindings: []
})

@View({
    templateUrl: "templates/main.component.html",
    styleUrls: ['styles/out/components/main.component.css']
})

export class MainComponent {

    public test2 = "initial text";

    constructor(private cd: ChangeDetectorRef) {
        setTimeout(() => {
            this.test2 = "updated text"; 

            // as stated by the angular team: the following is required, otherwise the view will not be updated
            this.cd.markForCheck();

        }, 500);
    }
}