我正在渲染器进程中构建一个 Angular 为 2 的 Electron 应用程序。我的主进程与套接字服务器对话。每当用户连接到此服务器或断开连接时,我希望在 View 中显示用户的状态。
为此,我使用 electron 的 ipc 从主进程向渲染进程发送消息,如下所示
socket.on('connect', function() {
mainWindow.webContents.send('socket-connection-status', true);
});
socket.on('disconnect', function() {
mainWindow.webContents.send('socket-connection-status', false);
});
在我看来,我有一个(简化的) Angular 分量,就像这样
const ipc = require('electron').ipcRenderer;
@Component({
selector: 'status-bar',
template: '{{status}}'
})
export class StatusBarComponent {
private status: string = "offline";
constructor() {
ipc.on('socket-connection-status', function(event, status) {
if (status===true) {
this.status = 'online';
} else {
this.status = 'offline';
}
console.log(status); // Successfully logs true|false
console.log(this.status); // Successfully logs online|offline
})
}
}
我成功地记录了来自主进程的消息。
问题是 Angular 2 不“知道” Electron 的 IPC,因此不会触发 status
的变化检测。我见过几个人在这个问题上苦苦挣扎,但还没有找到“真正”的解决方案。
我尝试通过注入(inject) ApplicationRef
、ChangeDetectorRef
和 ngZone
(引用:Triggering Angular2 change detection manually)来解决它,但没有任何方法provided(分别为tick()
、detectChanges()
、run()
)恰好提供了解决方案。
显然,“在”ipc.on
中,我无法引用我的类的属性/方法/注入(inject),因为我遇到了错误:例如,这个 ( https://github.com/JGantner/angular2_change_detection_issue/blob/master/browser/security-level-indicator-component.ts) 解决方案(我发现不是非常优雅)导致 Uncaught TypeError: Cannot read property 'markForCheck' of undefined
。
有人可以帮我解决如何在我的案例中进行变更检测吗?
编辑(破解):
我找到的一种方法,我至少可以获得我需要/想要的功能:
status-bar.component.ts
:
const ipc = require('electron').ipcRenderer;
import { SocketStatusService } from '../services/socket-status.service';
@Component({
selector: 'status-bar',
template: '{{status}}'
})
export class StatusBarComponent {
private status: string = "offline";
status$: Subscription;
constructor(private socketStatusService: SocketStatusService, private ref: ApplicationRef) {
ipc.on('socket-connection-status', function(evt, status) {
if (status===true) {
this.service.updateSocketStatus('online');
} else {
this.service.updateSocketStatus('offline');
}
}.bind({service: socketStatusService}))
this.status$ = this.socketStatusService.socket_status$.subscribe(
status => {
this.status = status;
this.ref.tick();
}
)
}
socket-status.service.ts
:
@Injectable()
export class SocketStatusService {
private socket_status = new BehaviorSubject<string>("offline");
socket_status$ = this.socket_status.asObservable();
updateSocketStatus(status: string) {
this.socket_status.next(status);
}
}
虽然这行得通,但我觉得必须有一种更优雅的方式来实现这种行为。
不过,最好的情况是直接在 ipc 回调中设置组件的类属性并触发更改检测……到目前为止,我还没有能够让它工作,所以我们将不胜感激。
(p.s. 另外,我不确定为什么我必须手动触发 this.ref.tick()
,这不是我记得在早些时候触发流变化检测时必须做的事情angular 2 的 beta 版本...)
最佳答案
this.status
设置在错误的对象上,markForCheck
也因此不起作用。事件处理程序应该是一个箭头,以便提供适当的上下文。
在适当的 this
上下文中,任何已知的触发变化检测的方法都应该有效。
例如
ipc.on('...', (evt, status) => {
...
this.changeDetectorRef.detectChanges();
});
或者
ipc.on('...', (evt, status) => {
setTimeout(() => {
...
});
});
关于angular - 在 Angular 2 中使用 ipcRenderer;触发变化检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40331285/