无法使用具有ngClass绑定的可观察对象更新视图

时间:2019-11-03 15:52:25

标签: angular electron angular-changedetection

我有一个启动外部应用程序的Electron / Angular应用程序,我正在监视那些服务是否正在运行,并在页脚中显示绿色/红色指示器以表明这一点。我正在使用Electron IPC API将设备状态从Electron传递到Angular。这一切都正常,并且我收到了可以在Angular中收听的发射事件。

我有一个监听IPC状态更新的服务

this.electronService.ipcRenderer.on(IpcChannels.SERVICE_STATUSES_UPDATE, (event, { deviceStatus }) => {
  // sending the new values through a private subject. There is a public
  // observable for the subject which consumers use. This works, i
  // receive updates when the services are stopped/started
  this.deviceStatus.next(deviceStatus);
});

在我的组件模板中

<span class="bottom-icon dot"
  [ngClass]="{'inactive': !(deviceStatusService.deviceStatus$ | async)}"></span>

<span>{{'FooterBar.deviceLabel' | translate}}</span>

这是失败的地方。该类永远不会更新为具有“非活动”类。我花了几个小时弄弄它,然后才偶然发现它确实在工作。 Angular不会重新渲染或更改,我猜是因为我发现,随着服务启动的延迟,当我的应用在状态更改后但在更改回原始值之前发出网络请求时,角度将重新渲染。而且确实会更新。但随后,在服务重新启动之后,它将再次更新,直到其他原因触发了角度更新。

我没有OnPush更改检测策略。我试着注入一个ChangeDetectionRef并让组件文件自己监听可观察对象,并在ChangeDetectionRef上运行detectChanges()。

如果我在初始化时将其添加到我的服务中,并且只是手动/随机更新了可观察对象,它实际上可以立即工作,但是当我切换回仅从ipc渲染器处理程序中发出新值时,则不会。

interval(5000)
  .subscribe(_ => {
    this.posPrintStatus.next(Math.random() > .5 ? true : false);
    this.cePosStatus.next(Math.random() > .5 ? true : false);
  });

对于这个程序性问题或我不了解的角度变化检测问题,我感到困惑。

如果我可以提供与此相关的其他代码/上下文,请告诉我。

1 个答案:

答案 0 :(得分:0)

答案很简单,但我从未遇到过这个问题,也从未考虑过。

这是因为IPC通信发生在Angular区域之外。我必须将NgZone实例注入我的服务并使用NgZone.run()才能更新角度区域内的可观察值。