绑定到控制器范围的服务更改不可见

时间:2014-03-24 12:29:33

标签: angularjs angularjs-ng-repeat

我有一项服务来保存对多个控制器很重要的数据(在关联数组中)。此服务保存的数据是异步更新的。在我的控制器中,我在范围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;
}

2 个答案:

答案 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

Updated fiddle

答案 1 :(得分:1)

作为对Khanh TO答案的修改,我要说避免$rootScope.$apply(),使用$timeout尝试在下一个摘要中将更改应用于数据,从而避免在最终结果时出现错误并发$apply's并消除滞后。我会这样做:

myApp.service('differentService', function (myService, $rootScope) {
    $timeout(function(){
        myService.nums[myService.total+'idx']=myService.total++;
    });
});