我尝试在websocket事件返回更新的数据后更新我的视图。
我在我的应用程序中注入了一个服务,并在服务上调用getData()方法。此方法向我的NodeJS服务器发出一个socket.io事件,该服务器又执行外部api调用并解析一些数据。 NodeJS服务器然后使用我在服务中收听的新数据发出一个成功事件。当返回成功事件时,我会更新我的视图中引用的服务的属性。
我已经搜索了几天,所有我发现是博客文章说这个变化应该是无缝的,或者我需要以某种方式整合zone.js,或尝试使用相同的逻辑使用表单(但是我试图做到这一点没有用户交互)。没有什么似乎对我有用,我有点沮丧。
例如:
让我说我收到一个字符串数组,我想创建一个未排序的列表。
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
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
<div> <h2>My List</h2> <ul> <li *ng-for="#item of mySvc.myList">Item: {{item}}</li> </ul> </div>
有趣的是,我发现如果我在组件中加入了一个超时,该更新会在成功回调更新someList属性之后更新我在视图中设置的任意属性,那么两个属性值都将同时正确更新。
例如:
新的app.ts
import {Component,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]);
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来识别数据在“成功”事件之后改变而不更新其他属性?
有没有使用NgFor指令丢失的东西?
所以我终于找到了一个我喜欢的解决方案。按照这个帖子
How to update view after change in angular2 after google event listener fired中的答案,我更新了zone.run()中的myList,现在我的数据在我的视图中按预期更新。
原文链接:https://www.f2er.com/angularjs/145110.htmlMyService.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); }); }); } }