WebSocket Service update Scope in Angular (Utilisation de ngWebSocket)?

J'essaie d'obtenir des données provenant d'une mémoire Web pour mettre à jour automatiquement la valeur dans la portée d'un contrôleur.

Mon service:

mimosaApp.service("Device", function ($websocket) { var self = this; var ws = $websocket.$new({ url: "ws://" + window.location.host + ":81", //mock: true, reconnect: true }); this.data = {}; ws.$on("$open", function() { ws.$emit("get", "device"); }); ws.$on("$message", function (message) { console.log("WS Received", message); for(var key in message) { self.data[key] = message[key]; } console.log(self.data); // At this point, self.data contains the proper data. }); this.send = function (obj) { ws.$emit("set", obj); }; }); 

Et mon contrôleur simple:

 angular.module("MimosaApp").controller("PageController", ["Device", "$scope", "$http", function(Device, $scope, $http) { $scope.device = Device; }]); 

Lorsqu'une connexion socket est effectuée, le navigateur envoie un message demandant des données (l'événement $ open). Lorsqu'il reçoit une réponse, il met à jour l'objet Device.data avec l'objet JSON.

Mais je ne vois pas que cela se reflète dans la portée / la vue de mon contrôleur. Si à l'intérieur du contrôleur, je définis quelque chose comme Device.data.name ='blah'; Je peux voir la propriété du nom dans la portée / la vue du contrôleur.

Je suis un peu nouveau chez Angular si désolé si ma question n'a pas de sens. 🙂

Ma vue essaie de l'utiliser comme suit:

 <div class="container-fluid"> location <ul> <li ng-repeat="(key, value) in device.data"> {{key}}: {{ value }} </li> </ul> <p>{{device.data.face}}</p> </div> 

En ce qui concerne la source, il ne semble pas invoquer le cycle de synthèse en utilisant la scope.$apply dans $on gestionnaire $on . Ce qui signifie que angular ne connaît aucune mise à jour de ses liaisons de visualisation, de sorte qu'aucun changement ne se reflète dans la vue. Donc, vous devriez le faire manuellement dans votre service, vous pouvez soit injecter un $rootScope soit simplement un $timeout d' $timeout pour déclencher un cycle de synthèse.

Exemple:-

Injectez $timeout

  ws.$on("$message", function (message) { console.log("WS Received", message); for(var key in message) { self.data[key] = message[key]; } console.log(self.data); // At this point, self.data contains the proper data. $timeout(angular.noop); //<-- just invoke a dummy digest }); 

$rootScope

  ws.$on("$message", function (message) { console.log("WS Received", message); for(var key in message) { self.data[key] = message[key]; } console.log(self.data); // At this point, self.data contains the proper data. $rootScope.$apply(); //invoke digest }); 

Ou même créer une promesse fictive dans votre service en utilisant $q .

 mimosaApp.service("Device", function ($websocket, $q) { var self = this; var _dummyPromise = $q.when(); //<-- here var ws = $websocket.$new({ url: "ws://" + window.location.host + ":81", //mock: true, reconnect: true }); //... ws.$on("$message", function (message) { console.log("WS Received", message); for(var key in message) { self.data[key] = message[key]; } _dummyPromise.then(angular.noop); //<-- here }); this.send = function (obj) { ws.$emit("set", obj); }; }); 

La cause la plus probable est que le $ on callback ne déclenche pas de cycle de synthèse pour informer le reste de l'application de tout changement.

Vous pouvez le faire manuellement en injectant $ rootScope

 mimosaApp.service("Device", function ($rootScope, $websocket) 

Puis déclencher un résumé $ après la mise à jour de vos données

 ws.$on("$message", function (message) { console.log("WS Received", message); for(var key in message) { self.data[key] = message[key]; } if(!$rootScope.$$phase) { // prevents triggering a $digest if there's already one in progress $rootScope.$digest() } console.log(self.data); // At this point, self.data contains the proper data. });