角度:绑定到服务的可观察属性 - >值不会更新



我正在尝试使用BroadcastChannel API在两个浏览器选项卡/窗口之间进行通信。通信似乎在角度服务的两个实例之间工作,但未显示可观测值的变化。我试图主要使用async管道来实现这一点。

我在StackBlitz 有一个问题的演示

我有两个使用路由器显示的组件。(controldisplay(

我有一个服务(MessagingService(,其中我有BehaviorSubjectBroadcastChannel API通信。该服务被注入到这两个组件中。

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,数据中有正确的值。

编辑:附加测试显示,当按下更改本地值的按钮时,该值会更新。因此,这似乎是变化检测的一个问题。

如果在角度上下文之外(即外部(更改数据,则角度不会知道这些更改。您需要在组件中使用ChangeDetectorRefNgZone来使角度感知外部变化,从而触发变化检测。

在您的情况下,可能您的服务以某种方式超出了Angular的区域。这就是Angular无法检测变化的原因

这应该工作

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)
}
);
}
  1. ZONES IN ANGULAR
  2. UNDERSTANDING ZONES
  3. ANGULAR CHANGE DETECTION EXPLAINED

Forked StackBlitz

最新更新