Javascript 从电子容器IPC通道接收数据时,变化检测间歇性工作
我有一个应用程序正在侦听来自IPC渲染器通道的传入数据。以下是我的设置: 向angular应用程序发送数据的容器(主窗口): angular应用程序:Javascript 从电子容器IPC通道接收数据时,变化检测间歇性工作,javascript,angular,electron,ipc,angular2-changedetection,Javascript,Angular,Electron,Ipc,Angular2 Changedetection,我有一个应用程序正在侦听来自IPC渲染器通道的传入数据。以下是我的设置: 向angular应用程序发送数据的容器(主窗口): angular应用程序: constructor( private store: Store<fromStore.AppState>, private cd: ChangeDetectorRef, private zone: NgZone, ) {} ngOnInit() { this.isLoading = true;
constructor(
private store: Store<fromStore.AppState>,
private cd: ChangeDetectorRef,
private zone: NgZone,
) {}
ngOnInit() {
this.isLoading = true;
if (this.electronService.ipcRenderer) {
this.electronService.ipcRenderer.on('data-from-container', (event, data) => {
this.zone.run(() => {
if(data){
setTimeout(() => {
console.log(data) // verified data is always received
this.formData = data; // property that form uses to populate data in the dom
this.prepopulateForm(data) // method that places incoming data in ngrx store
}, 1000)
}
})
})
}
this.store.select('containerData').subscribe(data => {
setTimeout(()=> {
console.log(data) // data is always being set in ngrx
this.isLoading = false
}, 5000);
})
}
构造函数(
私家店,
私人cd:ChangeDetectorRef,
私人区域:NgZone,
) {}
恩戈尼尼特(){
this.isLoading=true;
if(this.electronService.ipcRenderer){
this.electronService.ipcRenderer.on('data-from-container',(事件,数据)=>{
此.zone.run(()=>{
如果(数据){
设置超时(()=>{
console.log(data)//始终接收已验证的数据
this.formData=data;//表单用于在dom中填充数据的属性
这个.prepopulateForm(data)//方法将传入数据放置在ngrx存储中
}, 1000)
}
})
})
}
this.store.select('containerData').subscribe(数据=>{
设置超时(()=>{
console.log(data)//数据总是在ngrx中设置
this.isLoading=false
}, 5000);
})
}
每次IPC通道发出“来自容器的数据”事件时,数据总是从我的OnInit调用接收,但数据并不总是在我的表单中设置!我注意到的模式通常是,当angular应用程序首次在容器内启动时,数据不会预先填充表单,在初始启动后,随后每次启动应用程序时,数据都会出现
我曾尝试使用ngZone、setTimeout和detectChange方法触发更改检测,以便Angular应用程序可以检测新设置的formData,但它无法始终预填充表单。关于如何解决这个问题有什么建议吗?我对电子有一个非常基本的知识,所以我将尝试向您展示这个想法。对我来说,您的问题来自视图的初始化。您没有丢失事件,因为您可以在控制台中看到它们,但不能在视图中看到它们,这加强了我的猜测 如代码所示,您只发送一个事件(我想它只是用于测试raison),我们希望在呈现视图时显示它 在组件中添加一个主题,该主题通知我们视图已初始化,如:
import{Subject,combineTest,fromEvent}来自'rxjs';
viewInitialized$=新主题();
...
ngAfterViewInit(){
this.viewInitialized$.next();
}
...
现在,我们可以使用combinelateest
操作符等待两个排放,一个来自ipcrederer
,另一个来自viewsinitialized$
在此之前,我们必须将ipc渲染器
转换为可观察的
。从这个响应中,我们可以执行fromEvent(ipcRenderer,'data-From-container')
。如果它不起作用,我们可以使用另一个主题,它会在每次我们在ipcRenderer.on()
中接收到某些内容时发出事件,第二个解决方案需要ngZone
恩戈尼尼特(){
...
const containerData$=fromEvent(this.electronService.ipcRenderer,“容器中的数据”);
this.subscription=CombineTest(containerData$,this.viewInitialized$).subscription(combined=>{
常数数据=组合[0];
this.formData=数据;
此.prepopulateForm(数据)
})
...
}
恩贡德斯特罗(){
this.subscription.unsubscripte();
}
希望这有帮助。试试:
如果(数据){setTimeout(()=>{this.zone.run(()=>{this.formData=data;…});},1000);}
。结果仍然一样:setTimeout
为什么在zone.run
中使用,哪一个与表单和数据绑定相关?如果您可以用最少的可复制代码创建git回购,我相信提供解决方案会很容易
constructor(
private store: Store<fromStore.AppState>,
private cd: ChangeDetectorRef,
private zone: NgZone,
) {}
ngOnInit() {
this.isLoading = true;
if (this.electronService.ipcRenderer) {
this.electronService.ipcRenderer.on('data-from-container', (event, data) => {
this.zone.run(() => {
if(data){
setTimeout(() => {
console.log(data) // verified data is always received
this.formData = data; // property that form uses to populate data in the dom
this.prepopulateForm(data) // method that places incoming data in ngrx store
}, 1000)
}
})
})
}
this.store.select('containerData').subscribe(data => {
setTimeout(()=> {
console.log(data) // data is always being set in ngrx
this.isLoading = false
}, 5000);
})
}