我正在尝试使用websockets设置一个简单的通知系统。
我有我的websocket服务:
import {Injectable} from '@angular/core';
import {Observable, Observer, Subject} from 'rxjs/Rx'
@Injectable()
export class WebSocketService {
private socket: Subject<MessageEvent>;
public connect(url): Subject<MessageEvent> {
if (!this.socket) {
this.socket = this.create(url);
}
return this.socket;
}
private create(url): Subject<MessageEvent> {
let ws = new WebSocket(url);
let observable = Observable.create(
(obs: Observer<MessageEvent>) => {
ws.onmessage = obs.next.bind(obs);
ws.onerror = obs.error.bind(obs);
ws.onclose = obs.complete.bind(obs);
return ws.close.bind(ws);
}
);
let observer = {
next: (data: Object) => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify(data));
}
},
};
return Subject.create(observer, observable);
}
}
通知服务包含通知:
import {Injectable} from '@angular/core';
import {Subject} from 'rxjs/Rx'
import {WebSocketService} from "./websocket.service";
@Injectable()
export class NotificationService {
public messages: Subject<Object>;
constructor(wsService: WebSocketService) {
let notificationUrl = `ws://localhost:4969/Notification`;
this.messages = <Subject<Object>>wsService
.connect(notificationUrl)
.map((response: MessageEvent): Object => {
return JSON.parse(response.data);
});
}
}
订阅服务通知主题的组件:
import {Component, OnInit, ElementRef} from '@angular/core';
import {Notification} from "./notification";
import {NotificationService} from "../../services/notification.service";
@Component({
selector: 'notifier',
templateUrl: 'notifier.component.html',
styleUrls: ['notifier.component.css'],
host: {
'(document:click)': 'onClickedOutside($event)',
},
})
export class NotifierComponent implements OnInit {
notifications: Notification[] =[];
constructor(private elementRef: ElementRef, private notificationService: NotificationService) {
}
ngOnInit() {
this.notificationService.messages.subscribe(notification => {
let not = new Notification(notification.title, notification.notificationTypes, notification.data);
console.log(not);
let index = this.notifications.findIndex(x=>x.title == not.title);
if (index ==-1) {
this.notifications.push(not);
}
else {
this.notifications[index].data.progress=not.data.progress;
}
console.log(this.notifications)
});
}
}
所以我的websocket服务器发送的通知可以由它的标题唯一标识。如果标题已存在于我的通知数组中,我会更新它的进度,否则我会推送它。
除了一件事,一切都很好。 我的观点并未更新每个通知更新,但如果我点击任何地方,点击事件将重新呈现,我会看到进度上升。
我已经阅读了一些关于Angular2如何传播数据的文章,并且从我的阅读中我已经了解到,当您订阅某个主题并且它的数据发生了变化时,它应该触发一个事件来重新渲染,但这显然不是这种情况。
我错过了什么? (目前使用Angular2.0.0-rc.5)
答案 0 :(得分:0)
我已经能够在这个问题的帮助下解决了我的问题:How to force a component's re-rendering in Angular 2?
这里的进一步参考是我在我的组件的订阅函数中添加的确切行:
this.applicationRef.tick();