无法使用带有 ngClass 绑定的可观察对象来更新视图
Can't get view to update using observables with ngClass binding
我有一个启动外部应用程序的 Electron/Angular 应用程序,我正在监视这些服务是否 运行 并在页脚中显示 green/red 指示符以表明这一点。我正在使用 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>
这是它失败的地方。 class 永远不会更新为 'inactive' class。我摆弄了好几个小时才意外地发现它确实在工作。 Angular 我猜只是没有重新渲染或获得更改,因为我发现随着服务启动的延迟,当我的应用程序在状态更改之后但在更改回之前发出网络请求时原始值然后 angular 将重新呈现。它确实会更新。但是在服务重新启动后,它不会更新,直到其他东西触发 angular 更新。
我没有 OnPush 变化检测策略。我尝试注入 ChangeDetectionRef 并使用组件文件自己监听可观察对象,并在 ChangeDetectionRef 上使用 运行 detectChanges()。
如果我在初始化时将它添加到我的服务中并且只是 manually/randomly 更新可观察对象,它实际上会立即工作,但是当我切换回仅从 ipc 渲染器处理程序中发出新值时,它会不是。
interval(5000)
.subscribe(_ => {
this.posPrintStatus.next(Math.random() > .5 ? true : false);
this.cePosStatus.next(Math.random() > .5 ? true : false);
});
我不知道这是程序问题,还是我不理解的 angular 变更检测问题。
如果我可以提供关于此的任何其他 code/context,请告诉我。
答案相当简单,但我从未 运行 进入这个问题,也从未想过它。
这是因为 IPC 通信发生在 Angular 区域之外。我必须将 NgZone 实例注入我的服务并使用 NgZone.run() 来更新 angular 区域内的可观察值。
我有一个启动外部应用程序的 Electron/Angular 应用程序,我正在监视这些服务是否 运行 并在页脚中显示 green/red 指示符以表明这一点。我正在使用 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>
这是它失败的地方。 class 永远不会更新为 'inactive' class。我摆弄了好几个小时才意外地发现它确实在工作。 Angular 我猜只是没有重新渲染或获得更改,因为我发现随着服务启动的延迟,当我的应用程序在状态更改之后但在更改回之前发出网络请求时原始值然后 angular 将重新呈现。它确实会更新。但是在服务重新启动后,它不会更新,直到其他东西触发 angular 更新。
我没有 OnPush 变化检测策略。我尝试注入 ChangeDetectionRef 并使用组件文件自己监听可观察对象,并在 ChangeDetectionRef 上使用 运行 detectChanges()。
如果我在初始化时将它添加到我的服务中并且只是 manually/randomly 更新可观察对象,它实际上会立即工作,但是当我切换回仅从 ipc 渲染器处理程序中发出新值时,它会不是。
interval(5000)
.subscribe(_ => {
this.posPrintStatus.next(Math.random() > .5 ? true : false);
this.cePosStatus.next(Math.random() > .5 ? true : false);
});
我不知道这是程序问题,还是我不理解的 angular 变更检测问题。
如果我可以提供关于此的任何其他 code/context,请告诉我。
答案相当简单,但我从未 运行 进入这个问题,也从未想过它。
这是因为 IPC 通信发生在 Angular 区域之外。我必须将 NgZone 实例注入我的服务并使用 NgZone.run() 来更新 angular 区域内的可观察值。