数据更新后Angular2视图未更改 [英] Angular2 View Not Changing After Data Is Updated

查看:306
本文介绍了数据更新后Angular2视图未更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在websocket事件返回更新后的数据后,我试图更新视图.

I am trying to update my view after a websocket event returns updated data.

我将服务注入到我的应用程序中,并在该服务上调用getData()方法.此方法向我的NodeJS服务器发出一个socket.io事件,该事件依次执行外部api调用并解析一些数据.然后,NodeJS服务器将发出一个成功事件,其中包含我在服务中侦听的新数据.返回成功事件后,我然后更新视图中引用的服务上的属性.

I injected a service into my app and call getData() method on the service. This method emits a socket.io event to my NodeJS server which in turn performs an external api call and parses some data. The NodeJS server then emits a success event with the new data that I listen for in my service. When the success event is returned I then update my property on the service that is referenced in my view.

但是,无论我怎么做,一旦属性更新,我都无法显示数据.

However no matter what I try I cannot get the data to show once the property is updated.

我搜索了几天,发现所有博客文章都说此更改应该是无缝的,或者我需要以某种方式合并zone.js,或者使用表单尝试相同的逻辑(但是我试图无需用户干预即可执行此操作).似乎对我没有任何帮助,我感到有些沮丧.

I have searched for a few days now and all I find are blog posts that say this change should be seamless, or that I need to incorporate zone.js somehow, or to try the same logic using forms (however im trying to do this without user interaction). Nothing seems to work for me and I am getting a bit frustrated.

例如:

让我们说我收到了一个字符串数组,我想用它们来创建一个未排序的列表.

Lets say I receive an array of strings that I want to create an unsorted list with.

app.ts

import {Component, View, bootstrap, NgFor} from 'angular2/angular2';
import {MyService} from 'js/services/MyService';

// Annotation section
@Component({
    selector: 'my-app',
    viewInjector: [MyService]
})
@View({
    templateUrl: 'templates/my-app.tpl.html',
    directives: [NgFor]
})

class MyComponent {
    mySvc:MyService;

    constructor(mySvc:MyService) {
        this.mySvc = mySvc;
        this.mySvc.getData();
    }
}   

bootstrap(MyComponent, [MyService]);

MyService.ts

MyService.ts

let socket = io();
export class MyService {
    someList:Array<string>;

    constructor() {
        this.initListeners();
    }

    getData() {
        socket.emit('myevent', {value: 'someValue'});
    }

    initListeners() {
        socket.on('success', (data) => {
            self.someList = data;
        });
    }
 }

my-app.tpl.html

my-app.tpl.html

<div>
    <h2>My List</h2>
    <ul>
        <li *ng-for="#item of mySvc.myList">Item: {{item}}</li>
    </ul>
</div>

足够有趣的是,我发现如果从成功回调中更新someList属性之后,如果我在组件中合并了一个超时,该超时更新了我在视图上设置的任意属性,则两个属性值将同时正确更新

Interesting enough, I have found that If I incorporate a timeout within my component that updates some arbitrary property that I set on the view after the someList property is updated from the success callback then both property values are updated correctly at the same time.

例如:

新app.ts

    import {Component, View, bootstrap, NgFor} from 'angular2/angular2';
    import {MyService} from 'js/services/MyService';

    // Annotation section
    @Component({
        selector: 'my-app',
        viewInjector: [MyService]
    })
    @View({
        templateUrl: 'templates/my-app.tpl.html',
        directives: [NgFor]
    })

    class MyComponent {
        mySvc:MyService;
        num:Number;

        constructor(mySvc:MyService) {
            this.mySvc = mySvc;
            this.mySvc.getData();
            setTimeout(() => this.updateNum(), 5000);
        }

        updateNum() {
            this.num = 123456;
        }
    }   

    bootstrap(MyComponent, [MyService]);

新的my-app.tpl.html

new my-app.tpl.html

<div>
    <h2>My List {{num}}</h2>
    <ul>
        <li *ng-for="#item of mySvc.myList">Item: {{item}}</li>
    </ul>
</div>

那么我应该如何使angular2在成功"事件之后识别出数据已更改,而又不更新其他属性?

So how should I go about getting angular2 to recognize that the data has changed after the 'success' event without updating some other property?

使用NgFor指令是否缺少某些内容?

Is there something I am missing with the use of the NgFor directive?

推荐答案

所以我终于找到了我喜欢的解决方案.按照这篇文章的答案 google事件监听器触发后,如何在angular2中进行更改后如何更新视图我在zone.run()中更新了myList,现在我的数据在视图中得到了预期的更新.

So I finally found a solution that I like. Following the answer in this post How to update view after change in angular2 after google event listener fired I updated myList within zone.run() and now my data is updated in my view like expected.

MyService.ts

MyService.ts

/// <reference path="../../../typings/tsd.d.ts" />

// Import
import {NgZone} from 'angular2/angular2';
import {SocketService} from 'js/services/SocketService';

export class MyService {
    zone:NgZone;
    myList:Array<string> = [];
    socketSvc:SocketService;

    constructor() {
        this.zone = new NgZone({enableLongStackTrace: false});
        this.socketSvc = new SocketService();
        this.initListeners();
    }

    getData() {
        this.socketSvc.emit('event');
    }

    initListeners() {
        this.socketSvc.socket.on('success', (data) => {
            this.zone.run(() => {
                this.myList = data;
                console.log('Updated List: ', this.myList);
            });
        });
    }
 }

这篇关于数据更新后Angular2视图未更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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