$ широковещательный работает асинхронно, должен быть синхронным

У меня есть контроллер с числом трансляций $rootScope.$, Которые обновляют содержимое директивы.

Первая трансляция $rootScope.$ Очищает все содержимое / данные, а другая заполняет их.

app.controller('MyController', function($scope, header) {

    $rootScope.$broadcast('clear');
    $rootScope.$broadcast('title', header.title);
    $rootScope.$broadcast('total', header.total);

});

Примечание: заголовок разрешается из моего $ stateProvider, например:

.state('index', {
        url: '/index',
        templateUrl: 'home.html',
        controller: 'MyController',
        resolve: {
            header:  function() {
                return {
                    title : 'Welcome to Home',
                    total : 6
                };
            }
        }
    })

директива:

app.directive('myDirective', function() {
    return {
        restrict: 'A',
        replace: true,
        scope: {},
        link: function(scope, element, attrs) {
            scope.$on("clear", function(event, val) {
                scope.Title = '';
                scope.Total = 0;
            });               
            scope.$on("title", function(event, title) {
                scope.Title = title;
            });
            scope.$on("total", function(event, total) {
                scope.Total = total;
            });
        },
        template:
            '<section>' +
                '<p>{{Title}} - {{Total}}</p>' +                        
            '</section>'
    }
});

Проблема, с которой я столкнулся, заключается в том, что при загрузке страницы трансляция $ title и total вызывается до завершения очистки.


ОБНОВИТЬ:

Плункер: http://plnkr.co/edit/o7wEFyIGh0284ZAc9VnS?p=preview

Всякий раз, когда в home.html директива будет скрыта - исправьте. Всякий раз, когда на cart.html, директива будет показывать - исправить.

Чтобы увидеть проблему, нажмите на корзину... Нажмите кнопку, чтобы увеличить счетчик. Затем вернитесь домой, затем обратно в корзину... счетчик не будет сброшен до 0

2 ответа

Решение

Как упомянуто в моем комментарии выше, проблема заключалась в том, что область действия. Общий в 'clear' был / не доступен в других.on приведениях. Итак, глобальная переменная была объявлена ​​и обновлена ​​в каждой трансляции:

app.directive('myDirective', function() {
  return {
    restrict: 'A',
    replace: true,
    scope: {},
    link: function(scope, element, attrs) {

      var localTotal = null;

      scope.$on("clear", function(event) {
        scope.Title = '';
        scope.Total = 0;
        localTotal = scope.Total;
      });
      scope.$on("showDirective", function(event, show) {
        scope.showDirective = show;
      });
      scope.$on("total", function(event, total) {
        if (localTotal !== 0) {
          console.log("in IF");
          scope.Total = total;
        }
        else {
          scope.Total = localTotal;
        }
      });
      scope.$on("title", function(event, title) {
        scope.Title = title;
      });
    },
    template: '<section>' +
      '<p ng-if="showDirective">{{Title}} - {{Total}}</p>' +
      '</section>'
  }
});

См. Плункер: http://plnkr.co/edit/2Xx99RzvQtaD9ntiod0d?p=preview

Вы должны использовать сервис для синхронизации следующим образом:

app.controller('MyController', function($scope, header, myDirectiveManager) {
  myDirectiveManager.getPromise().then(function(directive){
    directive.clear();
    directive.setTitle(header.title);
    directive.setTotal(header.total);
 });

});

оказание услуг

app.service('myDirectiveManager',function($q){
   var deferred = $q.defer();
   this.getDeffer = function(){
     return deferred;
   };
   this.getPromise = function(){
      return deferred.promise;
   }
});

директива

app.directive('myDirective', function() {
return {
    restrict: 'A',
    replace: true,
    scope: {},
    controller: function($scope, myDirectiveManager) {
        var fasade = {
           clear: function(event, val) {
            scope.Title = '';
            scope.Total = 0;
           },
           setTitle: function(event, title) {
            scope.Title = title;
           },
           setTotal: function(event, total) {
            scope.Total = total;
           }

        };
        myDirectiveManager.getDeffer().resolve(fasade);
    },
    template:
        '<section>' +
            '<p>{{Title}} - {{Total}}</p>' +                        
        '</section>'
    }
  });
Другие вопросы по тегам