我正在尝试使用BroadcastChannel API在两个浏览器选项卡/窗口之间进行通信。通信似乎在两个角度服务实例之间工作,但未显示可观察到的值的变化。我主要是使用async
管道来实现这一点。
我在StackBlitz有一个我的问题的演示
我有两个组件,使用路由器显示。(control
和display
)
我有一个服务(MessagingService
),其中有一个BehaviorSubject
和BroadcastChannel API
-communications。该服务被注入到两个组件中。
export class MessagingService {
private _value = 1;
valueSubject: BehaviorSubject<number> = new BehaviorSubject<number>(this._value);
value$: Observable<number> = this.valueSubject.asObservable();
private bc: BroadcastChannel = new BroadcastChannel('controlChannel');
constructor() {
this.bc.onmessage = this.handleEvent;
}
当我打开两个选项卡(一个在/control
中,一个在/display
中)时,我可以在/control
中增加值,并在控制台接收/display
中的新值,但是这些值不会被更新。
装订:<p>service value: {{ messenger.value$ | async }}</p>
注射:constructor(private messenger: MessagingService) { }
所以问题是我做错了什么?我在display
中进行了额外的订阅,触发了next
调用,但是异步绑定没有得到更新。我还在同一个选项卡中看到了正确的MessageEvent
,在数据中有正确的值。
编辑:附加测试显示,当按下用于更改本地值的按钮时,将更新该值。因此,这似乎是一个变化检测的问题。
发布于 2018-07-10 10:32:21
如果您在角度上下文之外(即外部)变异数据,那么角将不知道这些变化。您需要在组件中使用ChangeDetectorRef
或NgZone
,以便从角度上了解外部变化,从而触发更改检测。
在你的情况下,你的服务可能以某种方式突破了棱角的区域。这就是为什么角不能检测到变化
这应该能行
import { Component, OnInit, OnDestroy, NgZone } from '@angular/core';
@Component({
selector: 'app-display',
template:
//.....rest of the code
constructor(private messenger: MessagingService,private zone: NgZone,) {}
ngOnInit() {
this.data = new Data();
this.sub = this.messenger.value$.subscribe(
res => {
this.zone.run(() => this.data.value = res)
}
);
}
https://stackoverflow.com/questions/51270534
复制相似问题