AngularJs变量没有更新

时间:2014-03-29 03:56:29

标签: angularjs angularjs-scope pubnub

无法弄清楚此代码中的错误是什么。我已尝试仅在此处发布代码的相关部分。

控制器

myApp.controller('MessageCtrl', function ($scope, notificationService, $rootScope) {


   $scope.notificationService = notificationService;
   $scope.msgCount = 0;
   $scope.notificationService.subscribe({channel : 'my_channel'});

    $rootScope.$on('pubnub:msg',function(event,message){
        $scope.msgCount = $scope.msgCount + 1;
        //$scope.$digest();
    });

});

我的通知角色服务

myApp.factory('notificationService',['$rootScope', function($rootScope) {
    var pubnub = PUBNUB.init({
        publish_key   : '..',
        subscribe_key : '..'
    });

    var notificationService = {
        subscribe : function(subscription) {
            pubnub.subscribe({
                channel : subscription.channel,
                message : function(m){
                    $rootScope.$broadcast('pubnub:msg', m);
                }
            });

        }
    };
    return notificationService;
}]);

模板

<div>

    Count =  {{msgCount}}
</div>

问题

使用控制台日志&amp;使用业力测试我已确认当我从通知服务执行$rootScope.$on时,MessageCtrl中的$broadcast方法被调用。并且msgCount变量正在增加。但是,我没有看到更新的值反映在模板中,而没有运行 a $scope.$digest()。我很确定我不应该打电话给$scope.$digest,即Angular应该为我提供此绑定。

有趣的是,当我从另一个控制器尝试$rootScope.$broadcast时,模板中的msgCount增加了,而不必调用$scope.$digest()。

任何人都可以在这里帮助我。谢谢。

更新 感谢Peter并查看了Google小组讨论,将$broadcast包裹在$apply中就可以了。

$rootScope.$apply(function(){
                        $rootScope.$broadcast('pubnub:question', m);
                    });

1 个答案:

答案 0 :(得分:10)

您的$broadcast似乎发生在AngularJS之外,您需要通过调用$apply()通知您的应用,但最好在notificationService中进行操作。

至于$ broadcast和$ on触发申请/摘要,您可以阅读this post。 AngularJs源文件的简要概述确保$ broadcast不会自动应用更改(look here )。 $ broadcast只是呼叫听众,没有别的。

请在jsFiddle 上查看这个简单示例。

模板

<div ng-controller="myCtrl"> 
   <p>Count: {{ count }}</p>
   <button ng-click="fireEvent()">Fire Event</button>
</div>

控制器

angular.module("app", [])
.controller('myCtrl', function($scope, $rootScope, notificationService) {
    $scope.count = 0;
    notificationService.subscribe();
    $rootScope.$on('event', function() {
        console.log("event listener");
        $scope.count++;
    });

    $scope.fireEvent = function() {
       // it is ok here due to ngClick directve
       $rootScope.$broadcast('event', true);
    };
})

工厂

.factory('notificationService',['$rootScope', function($rootScope) {

    var notificationService = {
        subscribe : function() {
             setInterval(function(){
                 console.log("some event happend and broadcasted");
                 $rootScope.$broadcast('event', true);
                 // angular does not know about this 
                 //$rootScope.$apply();
             }, 5000);
        }
    };
    return notificationService;
}]);

当然,在这两种情况下,您都会看到事件监听器触发,但是ngClick会触发$ digest,而notificationService则不会。

此外,您可以在这个很好的答案https://stackoverflow.com/a/12491335/1274503

中获取有关将启动摘要的来源的一些信息。