从 Electron Container IPC Channel 接收数据时,Change Detection 会间歇性工作
Posted
技术标签:
【中文标题】从 Electron Container IPC Channel 接收数据时,Change Detection 会间歇性工作【英文标题】:Change Detection works intermittently when receiving data from Electron Container IPC Channel 【发布时间】:2019-11-24 15:35:18 【问题描述】:我有一个应用程序正在侦听来自 IPC 渲染器通道的传入数据。这是我的设置:
将数据发送到 Angular 应用程序的容器(主窗口):
mainWindow.loadURL('http://www.myangularapp.com') //where the angular app lives (example url).
mainWindow.webContents.on('did-finish-load', () =>
const data = name: "John Doe", address: "123 Main St", city: "NY"
mainWindow.webContents.send('data-from-container', data)
)
角度应用:
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);
)
每次 IPC 通道发出 'data-from-container' 事件时,数据总是从我的 OnInit 调用中接收,但数据并不总是在我的表单中设置!我注意到的模式通常是,当 Angular 应用程序首次在容器内启动时,数据不会预先填充表单,在初始启动后,每次启动应用程序时,数据都会出现。
我尝试使用 ngZone、setTimeout 和 detectChange 方法来触发更改检测,以便 Angular 应用程序可以检测到新设置的 formData,但它并不能始终如一地预填充表单。有关如何解决此问题的任何建议?
【问题讨论】:
试试:if (data) setTimeout(() => this.zone.run(() => this.formData = data; ... ); , 1000);
.
还是一样的结果:/
你为什么在zone.run
里面使用setTimeout
?
能否展示所有与表单和数据绑定相关的代码?
如果你能用最少的可重现代码创建一个 git repo,我相信提供一个解决方案会很容易
【参考方案1】:
我对电子有非常基本的了解,所以我会尝试向您展示这个想法。对我来说,您的问题来自视图的初始化。您不会丢失事件,因为您可以在控制台中看到它们,但在视图中看不到,这加强了我的猜测。
如您的代码所示,您只发送一个事件(我想它只是为了测试原因),我们希望在呈现视图时显示它。
在您的组件中添加一个主题,通知我们视图已初始化,例如:
import Subject, combineLatest, fromEvent from 'rxjs';
viewInitialized$ = new Subject();
...
ngAfterViewInit()
this.viewInitialized$.next();
...
现在我们可以等待两个发射,一个来自ipcRenderer
,另一个来自viewInitialized$
,使用combineLatest
运算符。
在此之前,我们必须将ipcRenderer
转换为Observable
。从这个SO 响应我们可以做fromEvent(ipcRenderer,'data-from-container')
。如果它不起作用,我们可以使用另一个主题,每次我们在ipcRenderer.on()
中收到某些内容时都会发出事件,第二种解决方案需要 ngZone。
ngOnInit()
...
const containerData$ = fromEvent(this.electronService.ipcRenderer, 'data-from-container');
this.subscription = combineLatest(containerData$, this.viewInitialized$).subscribe(combined =>
const data = combined[0];
this.formData = data;
this.prepopulateForm(data)
)
...
ngOnDestroy()
this.subscription.unsubscribe();
希望这会有所帮助。
【讨论】:
以上是关于从 Electron Container IPC Channel 接收数据时,Change Detection 会间歇性工作的主要内容,如果未能解决你的问题,请参考以下文章