我一直在开发一个webapp,我必须在websocket上接收消息并进行更改。
基本上,我有类似的东西:
var socketService = angular.module('socketService');
socketService.factory('Listen', function () {
// connect etc.
socket.onmessage = function (msg) {
lastMsg = msg;
console.log(msg); // this is instant
}
return {
lastMsg: function () {
return lastMsg;
}
}
});
我在控制器内部有另一个模块,我正在使用这个服务
var mainMod = angular.module('mainMod', ['socketService']);
// some more stuff
mainMod.controller('MainCtrl', function(Listen) {
$scope.$watch(Listen.lastMsg, function (newmsg, oldmsg) { // this is laggy
// do stuff here
});
});
问题是这样的:只要在套接字上收到消息,我的$watch
就不会触发。如果我console.log
服务中的所有套接字消息,日志会立即出现,但是$ watch需要自己的甜蜜时间来触发。而且,这是非常不规则的 - 我没有看到滞后的模式。
我认为这与Angular的嘀嗒声有关 - 而$ watch会在每个刻度上进行比较,但这会严重影响我的应用程序的性能。
一种可能的解决方法是使用$broadcast
,但我不希望采用这种方法。
我该怎么办?
答案 0 :(得分:3)
您的lastMsg
是原始的,而且您正在聆听$scope
lastMsg
$scope.$digest
,但您没有触发$scope.$apply
(通常通过{{ 1}},但更改时更安全$timeout
}周期。要使$watch
触发,您需要:
var socketService = angular.module('socketService');
socketService.factory('Listen', function ($timeout) {
var lastMsg;
// connect etc.
socket.onmessage = function (msg) {
$timeout(function(){ // acts as a $rootScope.$apply
lastMsg = msg;
console.log(msg);
});
}
return {
lastMsg: function () {
return lastMsg;
}
}
});
更好的方法是$rootScope.$emit
事件,这样你就可以在事件发出后立即收到:
var socketService = angular.module('socketService');
socketService.factory('Listen', function ($rootScope) {
// connect etc.
socket.onmessage = function (msg) {
$rootScope.$emit('socket', msg);
}
return {
};
});
var mainMod = angular.module('mainMod', ['socketService']);
// some more stuff
mainMod.controller('MainCtrl', function(Listen) {
// when you inject Listen, your service singleton will be initialized
$scope.$on('socket', function(event, msg) {
// do stuff here
});
});