最后的解决方案
我正在构建一个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');
});
});