Angular + Electron ipcRenderer事件状态问题

时间:2017-11-05 12:52:59

标签: angular event-handling electron

最后的解决方案

我正在构建一个Angular + Electron应用程序,我希望能够将图像资源直接放入桌面窗口,这将触发创建流程,我将图像保存到本地文件系统。

基础知识正在运行,但我已经走进了一个棘手的局面,似乎角度应用程序完全失去了它的状态感。当从电子主进程获取消息时,使用ipcRenderer监听消息“url-activated”,代码执行似乎与角度执行周期不同。

在ipcRenderer的回调中,我执行路线导航。这是事情变得怪异的地方。路线导航似乎卡在中间的某个地方,有时我卡在当前路线和下一个路线之间,这通过与应用程序交互得到解决(似乎当角度应用执行它的变化检测它处理一些先前执行的路径行动,如正确切换到下一条路线。)

此时的应用程序非常难以理解,我需要执行其他操作来使应用程序运行并执行以前的交互(例如,当我尝试打开选择框以查看选项时,这没有任何作用,但是当我打开sidenav时,会出现选择框选项)。换句话说,感觉应用程序运行时进程严重失去同步。

感觉这一切都归功于ipcRenderer事件,我可能无法正确处理它,但我找不到一个好的方法来解决它。这是当前解决方案的代码片段:

ngOnInit() {
  if (this.electronService.isElectronApp) {
    this.electronService.ipcRenderer.on('url-activated', (event, data) => {
      let json = JSON.parse(data);
      console.log('We\'ve gotten an url from the main process', json.url);

      this.assetService.setBase64(json.imgStr);
      this.assetService.setImagePath(json.url);

      this.navigateTo('/image/create');
    });
  }
}

在电子应用程序的主要流程中,我们有:

mainWindow.webContents.on('will-navigate', (event, url) => {
  event.preventDefault();
  console.log('Wants to navigate to ' + url);

  if (url.match('file:///')) {
    var path = url.substr(8, url.length);
    base64Img.base64(path, (err, data) => {
      mainWindow.webContents.send('url-activated', JSON.stringify({ url: url, imgStr: data }));
    });
  } else {
    base64Img.requestBase64(url, (err, res, body) => {
      mainWindow.webContents.send('url-activated', JSON.stringify({ url: url, imgStr: body }));
    });
  }
}

通过使用超时和手动更改检测进行一些调整,我得到它处于半工作状态,但在与DOM的基本交互方面仍然会遇到很多错误,所以感觉就像我与电子主进程的通信是所有这一切的罪魁祸首。

我正在使用ngx-electron插件进行通信的角度部分

你可以在我的github上找到完整的项目art-companion

对于我和其他可能遇到同样问题的人来说,了解这个问题的根源可能是一个很好的学习。

Cheerz!

解决方案

在收到@estus的评论之后,我对Zone进行了一些测试,似乎偶然发现了一个解决方案,这是它在代码中的样子:

this.electronService.ipcRenderer.on('url-activated', (event, data) => {
  this.ngZone.runOutsideAngular(() => {
    let json = JSON.parse(data);
    console.log('We\'ve gotten an url from the main process', json.url);

    this.assetService.setBase64(json.imgStr);
    this.assetService.setImagePath(json.url);
  });

  this.ngZone.runTask(() => {
    this.navigateTo('/image/create');
  });
});

0 个答案:

没有答案