Angular: привязка к наблюдаемому свойству сервиса -> значение не обновляется

Я пытаюсь установить связь между двумя вкладками / окнами браузера с помощью 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 в той же вкладке с правильным значением в данных.

РЕДАКТИРОВАТЬ: дополнительное тестирование показывает, что значение обновляется при нажатии кнопки для изменения локального значения. Так что, похоже, проблема с обнаружением изменений.

1 ответ

Решение

Если вы изменяете данные вне углового контекста (то есть извне), то angular не будет знать об изменениях. Вам нужно использовать ChangeDetectorRef или же NgZone в вашем компоненте для информирования о внешних изменениях под углом и, таким образом, запускает обнаружение изменений.

В вашем случае, вероятно, ваш сервис каким-то образом выйдет из зоны 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

Другие вопросы по тегам