【问题标题】:AngularJs variable not updatingAngularJs变量不更新
【发布时间】:2014-03-29 03:56:29
【问题描述】:

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

控制器

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();
    });

});

我的通知 Angular 服务

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>

问题

使用控制台日志和使用业力测试我已经确认,当我从 Notification Service 执行 $broadcast 时,MessageCtrl 中的 $rootScope.$on 方法会被调用。并且msgCount 变量正在增加。但是,我没有看到更新的值反映在 不运行 $scope.$digest() 的模板中。我很确定我不需要调用 $scope.$digest ,即 Angular 应该为我提供这个绑定。

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

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

更新 感谢 Peter 并查看了 google 小组讨论,将 $broadcast 包装在 $apply 中就成功了。

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

【问题讨论】:

    标签: angularjs angularjs-scope pubnub


    【解决方案1】:

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

    至于 $broadcast 和 $on 触发应用/摘要,您可以在 this post 中阅读。 AngularJs 源文件的简要概述让我确信 $b​​roadcast 不会自动应用更改 (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中获得有关将启动摘要 cicle 的来源的一些信息

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-12
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 2014-01-24
      • 1970-01-01
      相关资源
      最近更新 更多