没有收到我工厂发出的$ rootScope的事件

时间:2014-10-02 18:08:29

标签: javascript angularjs

我创建了一个工厂来提供我自己的Angular&strong <$> exceptionHandler 的实现。 该工厂在$ rootScope上发出一个事件,向侦听器发出错误信号。 我的监听器是在一个指令中定义的,该指令正在监视$ rootScope。$ on事件。在我的工厂实例拦截异常并发出错误事件的情况下,一切似乎都很好。然而,据称正在监听事件的指令从未接收过该事件。在指令??

中,侦听器会错过导致此事件的断开连接

澄清:事件依赖于完全在$ rootscope上发射和消耗,以避免在下游广播事件。这是设计的,并且以前工作过,或者至少看起来在httpLoader和httpErrorHandler中工作,我是根据几个使用相同策略的实现编写的。 http://plnkr.co/edit/N0JwYJdxPLur4xYZTUP1?p=info

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

angular.module('demo.services',[]);
angular.module('demo.directives',[]);
angular.module('demo',['demo.services','demo.directives']);

angular.module('demo')
.controller('demoCtrl', function($scope){
  $scope.message="Generate Error";
  $scope.generateError =function(){
    var x;
    x.foo.oops = ':(';
  }
});

angular.module('demo.services')
.factory('$exceptionHandler', function () {
    var $injector = angular.injector(['ng']);
    return function errorCatcherHandler(exception, cause) {
      rootScope = $injector.get('$rootScope');
      rootScope.$emit("httpError",exception);
      console.error(exception);
    };
});


angular.module('demo.directives')
.directive('ngHttpError', ['$rootScope',
  function ($rootScope) {
    return {
      scope: {
        title: '@',
      },
      template: '<div ng-click="showError=false"' +
                'ng-show="showError">'+
                'ERROR! {{errorModel | json}}' + 
                '</div>',
      link: function ($scope) {
        var showError;

        $scope.showError = false;
        $scope.errorModel = {};
        showError = $scope.showError;

        var initScope = function(e,m){
          console.log(m);
          $scope.errorModel = m;
          $scope.showError=true;
        }
        $rootScope.$on("httpError", initScope);
      }
    };
  }
]);

angular.bootstrap(document,['demo']);

1 个答案:

答案 0 :(得分:2)

请记住,$emit()会在范围层次结构中向上发送事件,$broadcast()会在层次结构中向下发送事件。由于$rootScope是“根”范围(最顶层/节点),因此在此处使用$broadcast()将事件“向下”发送到子范围是有意义的。

来自the docs

$emit()

  

通过范围层次结构向上调度事件名称,通知已注册的$ rootScope.Scope侦听器。

来自the docs

$broadcast()

  

将事件名称向下调度到所有子范围(及其子级),通知已注册的$ rootScope.Scope侦听器。

- 更新:

我已更新您的$exceptionHandler以注入$injector服务并执行$broadcast()而不是$emit() - 这似乎可以解决问题:

angular.module('demo.services')
.factory('$exceptionHandler', function ($injector) {
    //var $injector = angular.injector(['ng']);
    return function errorCatcherHandler(exception, cause) {
      rootScope = $injector.get('$rootScope');
      rootScope.$broadcast("httpError",exception.message);
      console.error(exception);
    };
});

顺便说一句,相关的问题/答案可以在这里看到:AngularJs/ .provider / how to get the rootScope to make a broadcast?