J'ai une application Electron / Angular qui démarre des applications externes et je surveille si ces services fonctionnent ou non et affiche des indicateurs verts / rouges dans un pied de page pour l'indiquer. J'utilise l'API Electron IPC pour communiquer l'état des appareils d'Electron à Angular. Tout fonctionne et je reçois des événements émis que je peux écouter dans Angular.

J'ai un service qui écoute les mises à jour de statut IPC

this.electronService.ipcRenderer.on(IpcChannels.SERVICE_STATUSES_UPDATE, (event, { deviceStatus }) => {
  // sending the new values through a private subject. There is a public
  // observable for the subject which consumers use. This works, i
  // receive updates when the services are stopped/started
  this.deviceStatus.next(deviceStatus);
});

Dans mon modèle de composant

<span class="bottom-icon dot"
  [ngClass]="{'inactive': !(deviceStatusService.deviceStatus$ | async)}"></span>

<span>{{'FooterBar.deviceLabel' | translate}}</span>

C'est là que ça échoue. La classe n'est jamais mise à jour pour avoir la classe «inactive». Je l'ai tripoté pendant des heures avant de découvrir accidentellement qu'il fonctionne réellement. Angular ne restitue pas ou n'obtient pas de modifications, je suppose parce que j'ai constaté qu'avec un retard de démarrage des services, lorsque mon application faisait une demande nette APRÈS que le statut ait changé mais avant qu'il ne revienne à la valeur d'origine, angulaire rendrait. et il serait en effet mis à jour. Mais après le redémarrage du service, encore une fois, il ne se mettait pas à jour jusqu'à ce que quelque chose d'autre déclenche angulaire pour la mise à jour.

Je n'ai pas la stratégie de détection de changement OnPush. J'ai essayé d'injecter un ChangeDetectionRef et de retirer le fichier composant en écoutant les observables moi-même et en exécutant detectChanges () sur ChangeDetectionRef.

Si j'ajoute cela à mon service lors de l'initialisation et que je mets à jour manuellement / aléatoirement les observables, cela fonctionne en fait instantanément, mais lorsque je reviens à n'émettre de nouvelles valeurs qu'à partir du gestionnaire de rendu ipc, cela ne fonctionne pas.

interval(5000)
  .subscribe(_ => {
    this.posPrintStatus.next(Math.random() > .5 ? true : false);
    this.cePosStatus.next(Math.random() > .5 ? true : false);
  });

Je ne sais pas si c'est un problème de programmation ou un problème de détection de changement angulaire que je ne comprends pas.

S'il y a un autre code / contexte à ce sujet que je peux fournir, faites-le moi savoir.

0
kamcknig 3 nov. 2019 à 18:52

1 réponse

La réponse était assez simple, mais je n'avais jamais rencontré le problème et n'y avais jamais pensé.

C'était parce que la communication IPC se déroulait en dehors de la zone angulaire. J'ai dû injecter une instance de NgZone dans mon service et utiliser NgZone.run () pour mettre à jour les valeurs observables à l'intérieur de la zone angulaire.

0
kamcknig 3 nov. 2019 à 15:59