$broadcast 异步工作,需要同步

$broadcast working asynchronously, need to be synchronous

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

第一个 $rootScope.$broadcast 正在清除所有 contents/data 而另一个填充它。

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

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

});

注意:header 是从我的 $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 的 $broadcast 似乎在清除完成之前被调用。


更新:

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

只要在 home.html 上,指令就会隐藏 - 正确。 每当在 cart.html 上时,指令将显示 - correct.

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

您应该像这样使用服务进行同步:

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

正如我在上面的评论中提到的,问题是 'clear' was/is 中的 scope.Total 在其他 .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>'
  }
});

查看 Plunker:http://plnkr.co/edit/2Xx99RzvQtaD9ntiod0d?p=preview