在角度2中使用ipcRenderer; 触发变化检测

Wil*_*ven 4 electron angular2-changedetection angular

我正在渲染器过程中构建一个角度为2的电子应用程序.我的主进程与套接字服务器通信.每当用户连接到此服务器或断开连接时,我希望在视图中显示用户的状态.

为此,我使用电子的ipc从主要向渲染器进程发送消息,就像这样

socket.on('connect', function() {
  mainWindow.webContents.send('socket-connection-status', true);
});
socket.on('disconnect', function() {
  mainWindow.webContents.send('socket-connection-status', false);
});
Run Code Online (Sandbox Code Playgroud)

在我看来,我有一个(简化的)角度组件,就像这样

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
    })
  }
}
Run Code Online (Sandbox Code Playgroud)

我成功地从主进程记录消息.

问题是角度2不"知道"电子的ipc,因此不会触发变化检测status.我看到有几个人在努力解决这个问题,但没有遇到过"真正的"解决方案.

我试图与注射来解决它ApplicationRef,ChangeDetectorRefngZone(参考:手动触发Angular2变化检测),但没有提供的方法(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();
    }
  )
}
Run Code Online (Sandbox Code Playgroud)

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

虽然这有效,但我觉得必须有一种更优雅的方式来实现这种行为.

最好的情况可能是直接在ipc回调中设置组件的类属性并触发更改检测的方法...到目前为止,我还没有能够使用它,所以任何帮助将不胜感激.

(ps另外,我不知道为什么我必须手动触发this.ref.tick(),这不是我记得必须做的事情来触发早期测试版角度2中的流的变化检测......)

Est*_*ask 5

this.status设置在错误的对象上,因此markForCheck也不起作用.事件处理程序应该是一个箭头,以便提供适当的上下文.

通过适当的this上下文,任何已知的触发变化检测的方

例如

ipc.on('...', (evt, status) => {
  ...
  this.changeDetectorRef.detectChanges();
});
Run Code Online (Sandbox Code Playgroud)

要么

ipc.on('...', (evt, status) => {
  setTimeout(() => {
    ...
  });
});
Run Code Online (Sandbox Code Playgroud)