我正在渲染器过程中构建一个角度为2的电子应用程序。我的主进程与套接字服务器通信。每当用户连接到此服务器或断开连接时,我希望在视图中显示用户的状态。
为此,我使用电子的ipc从主要向渲染器进程发送消息,就像这样
socket.on('connect', function() {
mainWindow.webContents.send('socket-connection-status', true);
});
socket.on('disconnect', function() {
mainWindow.webContents.send('socket-connection-status', false);
});
在我看来,我有一个(简化的)角度组件,就像这个
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
})
}
}
我成功记录了主进程的消息。
问题是角度2不“知道”电子的ipc,因此status
不会触发更改检测。我看到有几个人在努力解决这个问题,但没有遇到过“真正的”解决方案。
我尝试通过注入ApplicationRef
,ChangeDetectorRef
和ngZone
(参考:Triggering Angular2 change detection manually)来解决此问题,但没有提供任何方法(tick()
,detectChanges()
,run()
分别碰巧提供了解决方案。
显然,'在'ipc.on
内部,当我遇到错误时,我无法引用我的类'属性/方法/注入:例如,这个(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回调中设置组件的类属性并触发更改检测...到目前为止,我还没有能够使用它,所以任何帮助将不胜感激。
(ps另外,我不知道为什么我必须手动触发this.ref.tick()
,这不是我记得在早期测试版角度2中从流中触发变化检测所必须做的事情......)
答案 0 :(得分:5)
import os
import sys
import re
from subprocess import call
root_directory = os.getcwd()
print (root_directory)
regexp = re.compile(r'src[\/\\]NetCoreXunit.?$')
result = False
for child in os.walk(root_directory):
print (child[0])
if regexp.search(child[0]) is not None:
print ("Matched")
test_path = os.path.join(root_directory, child[0])
if os.path.isdir(test_path):
print ("IsDir")
print (test_path)
os.chdir(test_path)
call (["dotnet", "test", "-xml", "output.xml"])
if 'result="Fail"' in open("output.xml").read():
print (test_path + ": Failed tests detected")
result = True
else:
print (test_path + ": All tests passed")
os.chdir(root_directory)
if result:
print ("Failed tests detected")
sys.exit(1)
设置在错误的对象上,this.status
因此而无法正常工作。事件处理程序应该是一个箭头,以便提供适当的上下文。
使用正确的markForCheck
上下文,任何已知的触发变更检测的方法都应该有效。
例如
this
或者
ipc.on('...', (evt, status) => {
...
this.changeDetectorRef.detectChanges();
});