在 angular 2 中使用 ipcRenderer;触发变化检测
Using ipcRenderer in angular 2; trigger change detection
我正在构建一个在渲染器进程中使用 angular 2 的电子应用程序。我的主进程与套接字服务器对话。每当用户连接到此服务器或断开连接时,我希望在视图中显示用户的状态。
为此,我使用 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 没有'know' electron 的ipc,所以status
没有触发变更检测。我见过很多人都在为这个问题而苦苦挣扎,但还没有遇到 'true' 解决方案。
我尝试通过注入 ApplicationRef
、ChangeDetectorRef
和 ngZone
(参考:)来解决它,但是 none 提供的方法(分别为tick()
、detectChanges()
、run()
)恰好提供了解决方案。
显然,'within' ipc.on
我无法引用我的 class' properties/methods/injectables 因为我 运行 出错了:例如,这个 (https://github.com/JGantner/angular2_change_detection_issue/blob/master/browser/security-level-indicator-component.ts) 解决方案(我发现它不是很优雅)导致 Uncaught TypeError: Cannot read property 'markForCheck' of undefined
。
有人可以帮我解决如何在我的案例中进行变更检测吗?
编辑(破解):
我找到的一种方法,我至少获得了我 need/want:
的功能
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 回调中设置组件的 class 属性并触发更改检测......到目前为止我还没有能够让它工作,所以任何帮助将不胜感激。
(p.s。另外,我不确定为什么我必须手动触发 this.ref.tick()
,这不是我记得在早期 Beta 版本中触发流变化检测所必须做的事情angular 2...)
this.status
设置在错误的对象上,因此 markForCheck
也不起作用。事件处理程序应该是一个箭头,以便提供适当的上下文。
在适当的 this
上下文中,任何已知的触发变化检测的方法都应该有效。
例如
ipc.on('...', (evt, status) => {
...
this.changeDetectorRef.detectChanges();
});
或
ipc.on('...', (evt, status) => {
setTimeout(() => {
...
});
});
我正在构建一个在渲染器进程中使用 angular 2 的电子应用程序。我的主进程与套接字服务器对话。每当用户连接到此服务器或断开连接时,我希望在视图中显示用户的状态。
为此,我使用 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 没有'know' electron 的ipc,所以status
没有触发变更检测。我见过很多人都在为这个问题而苦苦挣扎,但还没有遇到 'true' 解决方案。
我尝试通过注入 ApplicationRef
、ChangeDetectorRef
和 ngZone
(参考:tick()
、detectChanges()
、run()
)恰好提供了解决方案。
显然,'within' ipc.on
我无法引用我的 class' properties/methods/injectables 因为我 运行 出错了:例如,这个 (https://github.com/JGantner/angular2_change_detection_issue/blob/master/browser/security-level-indicator-component.ts) 解决方案(我发现它不是很优雅)导致 Uncaught TypeError: Cannot read property 'markForCheck' of undefined
。
有人可以帮我解决如何在我的案例中进行变更检测吗?
编辑(破解):
我找到的一种方法,我至少获得了我 need/want:
的功能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 回调中设置组件的 class 属性并触发更改检测......到目前为止我还没有能够让它工作,所以任何帮助将不胜感激。
(p.s。另外,我不确定为什么我必须手动触发 this.ref.tick()
,这不是我记得在早期 Beta 版本中触发流变化检测所必须做的事情angular 2...)
this.status
设置在错误的对象上,因此 markForCheck
也不起作用。事件处理程序应该是一个箭头,以便提供适当的上下文。
在适当的 this
上下文中,任何已知的触发变化检测的方法都应该有效。
例如
ipc.on('...', (evt, status) => {
...
this.changeDetectorRef.detectChanges();
});
或
ipc.on('...', (evt, status) => {
setTimeout(() => {
...
});
});