我有一项服务来保存对多个控制器很重要的数据(在关联数组中)。此服务保存的数据是异步更新的。在我的控制器中,我在范围myService上创建一个变量,并为其分配服务。然后,在我看来,我将数据引用为myService.theInterestingData。如果这很重要,在视图中,我在ng-repeat中引用了interestingData assoc数组。
出于某种原因,当数据更新时(我得到控制台日志),可见页面不会改变,但如果我执行一些UI动作(例如打开快照抽屉http://jtrussell.github.io/angular-snap.js/),那么数据已更新,但进一步更改还需要一些UI操作才能显示。
我一定是做错了。有关如何解决此问题的任何建议?我想也许我需要$ apply来调用,但数据是在服务上没有引用控制器的,我需要在其范围内申请
查看这两个版本的小提琴。两者都显示相同的日志记录,但是一个(不出所料地使用$ interval http://jsfiddle.net/a6Nhs/5/)会更新"屏幕" (我在这里谈论什么?DOM?)和另一个(window.setInterval http://jsfiddle.net/a6Nhs/4/)没有。在我的实际应用程序中,它不是导致异步更新的间隔,而是通过websocket接收信息,因此对我来说解决方案并不像更改为$ interval那么容易。
HTML:
<div ng-controller="MyCtrl">
Hello, {{name}}!
{{numsService}}
<li ng-repeat="(key,val) in numsService.nums">
{{key}} | {{val}}
</li>
</div>
和js:
var myApp = angular.module('myApp',[]);
//myApp.directive('myDirective', function() {});
myApp.service('myService', function() {
this.nums={};
this.total = 0;
});
myApp.service('differentService', function(myService, $interval){
$interval(function(){ //using $interval works, using window.setInterval does not
console.log('diffService');
myService.nums[myService.total+'idx']=myService.total++;
console.log(myService.nums);
}, 1000);
});
function MyCtrl($scope, myService, differentService) {
$scope.name = 'Superhero';
$scope.numsService = myService;
}
答案 0 :(得分:1)
您可以尝试$ apply on $ rootScope:
myApp.service('differentService', function(myService, $rootScope){
window.setInterval(function(){
$rootScope.$apply(function(){
console.log('diffService');
myService.nums[myService.total+'idx']=myService.total++;
console.log(myService.nums);
});
}, 1000);
});
通常,当您在范围上调用$ apply(exp)时,它实际上会评估exp,然后在根范围上调用$ digest()。看一下这个AngularJS service rootscope
答案 1 :(得分:1)
作为对Khanh TO答案的修改,我要说避免$rootScope.$apply()
,使用$timeout
尝试在下一个摘要中将更改应用于数据,从而避免在最终结果时出现错误并发$apply's
并消除滞后。我会这样做:
myApp.service('differentService', function (myService, $rootScope) {
$timeout(function(){
myService.nums[myService.total+'idx']=myService.total++;
});
});