我的websocket连接有一个服务,这个服务在函数中返回客户端是否实际连接的实际状态。 我简化了我的代码,这些代码片段是我的问题的一个小例子:
myApp.factory('Websocket', function() {
//the status boolean whether connected or not
var bool = true;
//small mock for the status change
setInterval(function() {
bool = !bool;
}, 1000);
//i've made the value of the status variable accessable in a function or the variable itself
return {
status: function() {
return bool;
},
var: bool
}
});
现在我尝试将状态值应用于控制器中的范围:
myApp.controller('Ctrl', function(Websocket, $scope) {
//method 1
$scope.status = Websocket.status();
//method 2
$scope.$watch(function() {
return Websocket.status();
}, function(newVal) {
$scope.status = newVal;
});
});
...但是这两种方法都不起作用,也没有为这个html更新$ scope变量:
<div ng-app="myApp">
<div ng-controller="Ctrl">
method1: {{status}}
</div>
</div>
这是一个codepen:http://codepen.io/anon/pen/bVjaBa?editors=101
感谢您的帮助!
答案 0 :(得分:2)
问题出在Nikos上面提到:你正在改变摘要循环之外的变量值,所以angular不跟随变化。
使用$scope.$apply
是一种选择,但在这种情况下,我更倾向于使用$interval
而不是setInterval
。
myApp.factory('Websocket', function($interval) {
var bool = true;
$interval(function() {
bool = !bool;
}, 1000);
return {
status: function() {
return bool;
},
var: bool
}
});
看到它正常工作here。
答案 1 :(得分:1)
问题在于,对Angular监视的数据进行的任何“外部”更改都必须调用scope.$apply()
以供观察者更新(此处观察者是来自{{status}}
表达式的UI)。在codepen中,解决方案很简单:使服务依赖于$rootScope
并在区间函数中调用$rootScope.$apply()
:
myApp.factory('Websocket', function($rootScope) {
...
setInterval(function() {
bool = !bool;
$rootScope.$apply();
}, 1000);
...
});
必须对真实服务做类似的事情,关键概念是:(1)你必须调用$apply()
和(2)无法访问特定范围,只需使用$rootScope