我有一个页面,它在页面加载时接收一组数据,并使用*ngFor
指令显示它。还有一个连接到Web Socket以接收更新的数据。在这个例子中,它是乘船游览的时间表。我的问题是我不确定如何使用来自WS的新数据更新页面加载数据。到目前为止,我有这段代码:
timeTableService.service.ts - 获取页面加载初始数据的服务
import { Injectable } from '@angular/core';
import { ApiService } from './api.service';
@Injectable()
export class TimeTableService {
constructor(
private apiService: ApiService,
) { }
getInitialTimes() {
return this.apiService.get('/timetable/')
}
}
liveTimeTableService.service.ts - 使用this library连接处理Web套接字连接的服务
import { Injectable } from '@angular/core'
import { QueueingSubject } from 'queueing-subject'
import { Observable } from 'rxjs/Observable'
import websocketConnect from 'rxjs-websockets'
import 'rxjs/add/operator/share'
@Injectable()
export class LiveTimeTableService {
private inputStream: QueueingSubject<any>
public messages: Observable<any>
public connect() {
this.messages = websocketConnect(
'ws://www.timetables.com:8080',
this.inputStream = new QueueingSubject<string>()
).messages.share()
}
public send(message: string):void {
this.inputStream.next(message)
}
}
timeTable.component.ts - 显示时间表的组件
import { Component, OnInit } from '@angular/core';
import { TimeTableService, LiveTimeTableService } from './shared';
import { Subscription } from 'rxjs/Subscription'
@Component({
selector: 'app-time-table',
templateUrl: './time-table.component.html',
})
export class TimeTableComponent implements OnInit {
private timeTable: any;
private socketSubscription: Subscription
constructor(
private timeTableService: TimeTableService,
private liveTimeTableService: LiveTimeTableService,
) {}
ngOnInit() {
this.liveTimeTableService.connect();
this.liveTimeTableService.send('SUBSCRIBE times')
// subscribe to any message updates
this.socketSubscription = this.liveTimeTableService.messages
.subscribe((timesUpdate) => {
this.timeTable = timesUpdate;
})
// get the time table data on page load
this.timeTableService.getInitialTimes()
.subscribe((timeTable) => {
this.timeTable = timeTable
})
}
ngOnDestroy() {
this.socketSubscription.unsubscribe()
}
}
HTML模板
<div *ngFor="let boat of timeTable">
{{ boat.name }}
<span *ngFor="let time of boat.times">{{time}}</span>
</ldiv>
数据看起来像这样
WS Message data(包含时间和状态等次要更新):
问题是每次来自WS的新消息都会重置this.timeTable
,并且整个*ngFor
指令再次运行并重建dom。我想要做的是使用WS消息中的新值更新*ngFor
中的任何'time'表达式,然后应用css类来通知用户更改:
任何建议或建议如何激活这一点将不胜感激。并为很长的帖子道歉!
答案 0 :(得分:0)
也许使用trackBy选项,就像在这个答案中一样:
Angular 2 - with ngFor, is it possible to update values without rebuilding the dom?
因此,您的代码将类似于:
查看:强>
<div *ngFor="let boat of timeTable; let i = index; trackBy: trackByFn">
{{ boat.name }}
<span *ngFor="let time of boat.times">{{time}}</span>
</div>
<强>组件强>
trackByFn(index, item) {
return index;
}
作为参考,您应该使用:https://angular.io/guide/template-syntax#ngfor-with-trackby