angular - 在 Angular 2 中使用 ipcRenderer;触发变化检测

标签 angular electron angular2-changedetection

我正在渲染器进程中构建一个 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) ApplicationRefChangeDetectorRefngZone(引用: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/

相关文章:

javascript - 我如何为我的 Electron 应用程序创建后端

react-router - 使用Electron App进行Keycloak身份验证

angular - 某些事件未触发更改检测

typescript - NoProviderError 在 Angular 2 中使用 CanActivate

Angular 2 RC6 - 在 URL 中设置默认参数并重定向到带有参数的路由

javascript - Mac 上的屏幕视频捕获(包括鼠标光标)?

angular - 使用多个 slider 时通过特定 slider (更改)获取 slider 的值

angular - 输入数组的变化检测

angularjs - Angular 2 Http 测试多个连接

.NET Core 项目中的 Angular 12 - 路由不工作