2014-03-29 4 views
3

Невозможно выяснить, что такое ошибка в этом коде. Я пробовал только размещать соответствующие части кода здесь.Переменная AngularJs не обновляется

Контроллер

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

}); 

Мой Notification Угловая служба

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> 

Проблема:

Использование консоли журналов & с помощью кармы тестов я подтвердил, что метод $rootScope.$on в MessageCtrl становится называется, когда я делаю $broadcast из Notification Service. И что переменная msgCount получает инкремент. Однако я не вижу обновленного значения, которое отражается в шаблоне без пробега a $scope.$digest(). Я уверен, что мне не нужно будет звонить $scope.$digest, т. Е. Angular должен предоставить мне эту привязку.

Интересно, что когда я попробовал $rootScope.$broadcast от другого контроллера, то msgCount в шаблоне был увеличен без вызова $scope.$digest().

Может кто-нибудь любезно помочь мне здесь. Спасибо.

Update Благодаря Петру и глядя на групповое обсуждение Google, обернув $broadcast в $apply сделал трюк.

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

ответ

9

кажется, что ваш $broadcast происходит вне AngularJS и вы должны уведомить ваше приложение об этом с вызовом $apply(), но лучше делать это в notificationService.

Что касается $ broadcast и $ on trigger, то применить/дайджест вы можете прочитать в 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

Смежные вопросы