在后端和前端之间的 IPC 通信中更新 angular 组件时遇到问题
trouble updating angular component in IPC communication between back and front
我有一个 Electron (6) / Angular (8) 应用程序。
在前面(Angular)我通过IPCRenderer向后面发送消息。
在后面,IPCMain 接收消息并执行所需的操作,在示例中,获取文件列表。
后端一次一个地将文件发送到前端(同样是 IPC)。
前台接收消息,因为我"console.log"每个文件都是我收到的。
但是,当我用文件填充一个数组时,它不会显示在组件中,直到我在页面上单击。
知道我做错了什么吗?
在 main.ts 中:
ipcMain.on('get-files', (event, data) => {
const path = data;
fs.readdir(path, (err, files) => {
files.forEach(file => {
this.log.info(file);
event.reply('new-file', file);
});
});
});
file.service.ts :
import { Injectable } from '@angular/core';
import { ElectronService } from 'ngx-electron';
import { BehaviorSubject, Observable } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class FilesService {
public _file: BehaviorSubject<any> = new BehaviorSubject(null);
constructor(private els: ElectronService) {}
setFile(value) {
if (value) {
this._file.next(value);
}
}
listfiles(path: string): Observable<string[]> {
const result = new Observable<string[]>(observer => {
const files = this.els.ipcRenderer.sendSync('listfiles', { path });
observer.next(files);
});
return result;
}
getFiles(path: string) {
this.els.ipcRenderer.send('get-files', path);
}
}
在 test.component.ts 中:
import { Component, OnInit } from '@angular/core';
import { ElectronService } from 'ngx-electron';
import { ProjectsService } from '../../services/projects.service';
import { FilesService } from './../../services/files.service';
@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss'],
})
export class TestComponent implements OnInit {
constructor(private fileService: FilesService, private projectService: ProjectsService, private els: ElectronService) {}
files = [];
sPath = 'c:\';
ngOnInit() {
this.fileService._file.subscribe(file => {
if (file) {
this.files.push(file);
}
});
this.els.ipcRenderer.on('new-file', (event, file) => {
console.log(file);
this.fileService.setFile(file);
});
}
sendMsg() {
console.log('sendMsg');
this.files = [];
/* this.fileService.listfiles(this.sPath).subscribe(result => {
this.files = result;
}); */
this.fileService.getFiles(this.sPath);
}
newProject() {
console.log('newProject');
this.projectService.createProject('test.pj4').subscribe(result => {
console.log(result);
});
}
}
在 test.component.html 中:
<div id="test">
<div class="divbtn">
<button class="xx" mat-raised-button color="primary" (click)="sendMsg()">Test</button>
</div>
<div class="divbtn">
<button class="xx" mat-raised-button color="primary" (click)="newProject()">New Project</button>
</div>
<div *ngIf="files.length > 0">
<p *ngFor="let file of files">{{file}}</p>
</div>
</div>
在 class 中导入 NgZone
订阅事件并使用方法 run
。我没有使用 IPC,但是对于来自后端的推送事件它起作用了
this.els.ipcRenderer.on('new-file', (event, file) => {
console.log(file);
this.ngZone.run(() => this.fileService.setFile(file));
});
我有一个 Electron (6) / Angular (8) 应用程序。
在前面(Angular)我通过IPCRenderer向后面发送消息。
在后面,IPCMain 接收消息并执行所需的操作,在示例中,获取文件列表。
后端一次一个地将文件发送到前端(同样是 IPC)。
前台接收消息,因为我"console.log"每个文件都是我收到的。
但是,当我用文件填充一个数组时,它不会显示在组件中,直到我在页面上单击。
知道我做错了什么吗?
在 main.ts 中:
ipcMain.on('get-files', (event, data) => {
const path = data;
fs.readdir(path, (err, files) => {
files.forEach(file => {
this.log.info(file);
event.reply('new-file', file);
});
});
});
file.service.ts :
import { Injectable } from '@angular/core';
import { ElectronService } from 'ngx-electron';
import { BehaviorSubject, Observable } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class FilesService {
public _file: BehaviorSubject<any> = new BehaviorSubject(null);
constructor(private els: ElectronService) {}
setFile(value) {
if (value) {
this._file.next(value);
}
}
listfiles(path: string): Observable<string[]> {
const result = new Observable<string[]>(observer => {
const files = this.els.ipcRenderer.sendSync('listfiles', { path });
observer.next(files);
});
return result;
}
getFiles(path: string) {
this.els.ipcRenderer.send('get-files', path);
}
}
在 test.component.ts 中:
import { Component, OnInit } from '@angular/core';
import { ElectronService } from 'ngx-electron';
import { ProjectsService } from '../../services/projects.service';
import { FilesService } from './../../services/files.service';
@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss'],
})
export class TestComponent implements OnInit {
constructor(private fileService: FilesService, private projectService: ProjectsService, private els: ElectronService) {}
files = [];
sPath = 'c:\';
ngOnInit() {
this.fileService._file.subscribe(file => {
if (file) {
this.files.push(file);
}
});
this.els.ipcRenderer.on('new-file', (event, file) => {
console.log(file);
this.fileService.setFile(file);
});
}
sendMsg() {
console.log('sendMsg');
this.files = [];
/* this.fileService.listfiles(this.sPath).subscribe(result => {
this.files = result;
}); */
this.fileService.getFiles(this.sPath);
}
newProject() {
console.log('newProject');
this.projectService.createProject('test.pj4').subscribe(result => {
console.log(result);
});
}
}
在 test.component.html 中:
<div id="test">
<div class="divbtn">
<button class="xx" mat-raised-button color="primary" (click)="sendMsg()">Test</button>
</div>
<div class="divbtn">
<button class="xx" mat-raised-button color="primary" (click)="newProject()">New Project</button>
</div>
<div *ngIf="files.length > 0">
<p *ngFor="let file of files">{{file}}</p>
</div>
</div>
在 class 中导入 NgZone
订阅事件并使用方法 run
。我没有使用 IPC,但是对于来自后端的推送事件它起作用了
this.els.ipcRenderer.on('new-file', (event, file) => {
console.log(file);
this.ngZone.run(() => this.fileService.setFile(file));
});