我这里有这个简单的代码,但我不完全理解为什么服务不更新作用域变量。我相信这与 $scope 不再指向服务内变量的内存位置有关,但我不知道如何修复。
fooController.js
$scope.count = foo.cycleCount()
index.html
<div>{{count}}</div>
fooService.js
angular.module('app').factory('foo', function($timeout){
return cycleCount: function(){
var count = 1;
$interval(function(){
if (count === 5){
count = 1;
}else{
count++;
}
return count;
}), 2000);
return count;
}
});
我想要一种不会将 $timout 移动到 Controller 的解决方案,最好是不使用 $watch 的解决方案(尽管如果必须的话它必须)。
编辑返回的对象:
fooController.js
$scope.count = foo.cycleCount()
index.html
<div>{{count.num}}</div>
fooService.js
angular.module('app').factory('foo', function($timeout){
return cycleCount: function(){
var count = {num: 1 }
$interval(function(){
if (count.num === 5){
count.num = 1;
}else{
count.num++;
}
return count;
}), 2000);
return count;
}
});
最佳答案
您正在传递一个基元而不是一个对象。您可以做两件事:
- 将“count”包装在一个对象中并从服务返回该对象。这样范围值也会更新。
- 强制范围接受更改。这可以通过使用服务值监视或设置超时来更新它来完成。
- 在服务中具有注册和取消注册更新功能,请参阅下面的代码片段。
_
angular.module('app').factory('foo', function($interval, $parse){
countUpdaters = {};
var count = 1;
$interval(function(){
if (count === 5){
count = 1;
}else{
count++;
updateValues(countUpdaters, count);
}
}), 2000);
var updateValues = function(updaters, value) {
var keys = Object.keys(updaters);
var values = keys.map(function(v) { return updaters[v]; });
values.forEach(function(updater) {
$parse(updater.nameSpace)(updater.scope);
});
};
var services;
services = {
registerCountUpdater: function(scope, nameSpace) {
countUpdaters[scope.$id] = {
scope: scope,
nameSpace: nameSpace
};
// Auto-unregister on scope removal
scope.$on('$destroy', function() {
services.unregisterCountUpdater(scope);
});
},
unregisterCountUpdater: function(scope) {
delete countUpdaters[scope.$id];
}
};
return services;
});
关于javascript - 服务中的 $timeout 未更新范围变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27046751/