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. });