【问题标题】:Angular2, view not updating after variable changes in settimeoutAngular2,在settimeout中的变量更改后视图不更新
【发布时间】:2016-04-02 04:55:50
【问题描述】:

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

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

@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);

    }
}

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

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

{{ test2 }}

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

编辑:我正在使用的完整代码,包括引导程序和 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:

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

主组件.html

{{ test2 }}

【问题讨论】:

  • 我刚刚重建了您的最小 angular2 应用程序,但我确实得到了更新的文本结果。控制台中是否有任何错误?如果没有,你能提供更多的代码吗?就像您的 index.htmlmain.component.html 以及您引导应用程序的位置

标签: javascript typescript angular angular2-template


【解决方案1】:

应该可以。控制台还有其他错误吗?

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

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

【讨论】:

  • 谢谢,控制台没有错误。我已经用完整的代码更新了我的问题,我注意到你正在使用 import 'rxjs/Rx';而我不是。我在教程中看不到这一点。你这样做有理由吗?
  • 不不,你不需要它,我把我的另一个 plunker 分叉了,然后它离开了...... :( 正如蒂埃里所说,只需在你的 index.html 中包含 angular2-polyfills.min.js
  • 这对我来说完全适用于 angular 2.0,谢谢。
【解决方案2】:

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

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

您可以观看 Bryan Ford 解释其含义的视频:https://www.youtube.com/watch?v=3IqtmUscE_U

希望对你有帮助, 蒂埃里

【讨论】:

  • 就是这样!但我不明白。我曾经用 alpha 开发一些版本,这可以开箱即用。他们为什么默认不将这个包含在 angular2 包中?
  • 是的,同意! alpha 版本和 beta 版本之间存在一些差异......以前可以工作的东西现在不能再工作了。当您处于 Alpha 阶段时,这就是问题所在。否则我猜他们不会把它放入 angular2 包中,因为它实际上不是 angular2 ;-) 我的两分钱
【解决方案3】:

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

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

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

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

【讨论】:

    【解决方案4】:

    在 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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 2016-12-11
      • 2016-08-08
      • 1970-01-01
      • 1970-01-01
      • 2015-10-20
      • 1970-01-01
      相关资源
      最近更新 更多