简体   繁体   English

关于 ipc 事件的 Electron-Angular 打开客户端对话框

[英]Electron-Angular open client-side dialog on ipc event

I have a back-end notification that pops up a client-side angular-material dialog component.我有一个后端通知,它会弹出一个客户端角度材质对话框组件。 Sometimes, but not always, the dialog does not completely instantiate.有时,但并非总是如此,对话框不会完全实例化。 The constructor of the component is invoked, but nothing else in the lifecycle is called until the dialog closes.组件的构造函数被调用,但生命周期中的其他任何东西都不会被调用,直到对话框关闭。 Sometimes it works just fine and ngOnInit is invoked, too.有时它工作得很好并且ngOnInit也被调用。

The component that has the ipc subscription looks like this (I have also tried setTimeout and using Observable , neither with much success):具有 ipc 订阅的组件如下所示(我也尝试过setTimeout和使用Observable ,但都没有成功):

api.receive('hotkey', (event, arg) => {
  this.onHotkey(shortcut as Shortcut);
});
api.send('setHotkeyListener');

The hotkey implementation calls the same method as a button which does the this.dialog.open(...) business.热键实现调用与执行this.dialog.open(...)业务的按钮相同的方法。

The api is implemented via a contextBridge in preload.js as follows: api 是通过preload.jscontextBridge实现的,如下所示:

const {
  contextBridge,
  ipcRenderer
} = require("electron");

// Expose protected methods that allow the renderer process to use
// the ipcRenderer without exposing the entire object
contextBridge.exposeInMainWorld(
  "api", {
    sendSync: (channel, data) => {
      return ipcRenderer.sendSync(channel, data);
    },
    send: (channel, data) => {
      ipcRenderer.send(channel, data);
    },
    receive: (channel, func) => {
      ipcRenderer.on(channel, (...args) => func(...args));
    }
  }
);

I assume the problem is some missing context that angular isn't getting from the ipcRenderer code path;我认为问题是一些缺失的上下文,即 angular 没有从 ipcRenderer 代码路径中获取; do you know what I am missing?你知道我错过了什么吗?

This was difficult to find, but easy to fix.这很难找到,但很容易解决。 Hopefully my issue helps point others in the right direction, too.希望我的问题也有助于为其他人指明正确的方向。 I needed to use NgZone to let angular know that it needs to detect changes.我需要使用NgZone让 angular 知道它需要检测变化。

import { NgZone, OnInit } from '@angular/core';

// ...

declare const api: any;

export class AppComponent implements OnInit {
  constructor(private ngZone: NgZone) {}
  ngOnInit() {
    api.receive('hotkey', (event, arg) => {
      this.ngZone.run(() => this.onHotkey(arg as Shortcut));
    });
    api.send('setHotkeyListener');
  }
  // ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM