$ broadcast异步工作,需要同步

时间:2015-08-27 14:21:04

标签: javascript angularjs angularjs-scope angular-ui-router angular-broadcast

我有一个控制器,它有一些$ rootScope。$ broadcast,用于更新指令的内容。

第一个$ rootScope。$ broadcast正在清除所有内容/数据,而另一个填充它。

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

我遇到的问题是,在页面加载时,标题和总数的$ broadcast似乎在清除完成之前被调用。

更新

Plunker:http://plnkr.co/edit/o7wEFyIGh0284ZAc9VnS?p=preview

每当在home.html上,指令都会隐藏 - 正确。 每当在cart.html上,指令都会显示 - 正确。

要查看问题,请单击购物车...单击按钮增加计数器..然后返回主页,然后返回购物车...计数器将不会重置为0

2 个答案:

答案 0 :(得分:1)

您应该使用服务进行同步,如下所示:

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

指令

{{1}}

答案 1 :(得分:0)

正如我在上面的评论中所提到的,问题是在其他.on演员阵容中无法访问'clear'中的scope.Total。因此,在每次广播中声明并更新了一个全局变量:

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

请参阅Plunker:http://plnkr.co/edit/2Xx99RzvQtaD9ntiod0d?p=preview