Angular - 使用ngNotificationsBar

时间:2016-10-03 10:32:40

标签: javascript angularjs exception

我尝试使用ng-notifications-bar模块,我有这样的代码:

angular.module('app', [
    uiRouter,
    Common.name,
    Components.name,
    angularMaterial,
    'ngTable',
    'gridster',
    'ngNotificationsBar'
  ])
  .factory('$exceptionHandler', ['notifications', function(notifications) {
    return function(exception, cause) {
      notifications.showError({message: exception});
    };
  }]);

但得到了错误:

  

[$ injector:cdep]找到循环依赖项:$ rootScope< - notifications< - $ exceptionHandler< - $ rootScope< - $ timeout< - $$ rAF< - $ mdGesture

我已尝试修改库以使用$injector来获取$ timeout和$ rootScope,但这并没有帮助我们尝试使用$injector来获取{{1}在notifications工厂,但得到了同样的错误。

2 个答案:

答案 0 :(得分:3)

相当差的设计,从它看起来就像这个。由于依赖性,您无法以任何形式将$rootScope注入$exceptionHandler

您可以使用$injector来解决这些(手外)依赖性问题,您只需要确保在返回函数中使用注入的模块以确保在调用.get()依赖模块实际加载的时间。例如:

// won't not be available here
var rootScope = $injector.get('$rootScope');

return function(exception, cause) {
  // will be available here
  var rootScope = $injector.get('$rootScope');
};

这是因为$injector用于在运行时获取依赖项。

答案 1 :(得分:1)

有一个很好的干净的面向对象设计,以避免循环依赖:使用dependency inversion principle。创建可以附加处理程序的通用服务,并从run块进行设置。基本上所有其他解决方案都提出类似的建议,但使用角度之外的全局变量,或绕过自动依赖注入。

angular.module("App", [])
.factory("notifications", function($rootScope) {
  $rootScope.notifications = [];
  function showMessage(msg) {
    $rootScope.notifications.push(msg);
  }
  return { showMessage };
})
.factory("$exceptionHandler", function(MyExceptionService) {
  return function(e, cause) {
    MyExceptionService.fire(e, cause);
  };
})
.factory("MyExceptionService", function() {
  const handlers = [];
  return {
    addHandler(h) { handlers.push(h); },
    fire(e, cause) { handlers.forEach(h => { h(e, cause); }) }
  };
})
.controller("MyCtrl", function($scope) {
  $scope.clicked = () => {
    throw new Error("Error made");
  };
})
.run(function(MyExceptionService, notifications) {
  MyExceptionService.addHandler(err => {
    notifications.showMessage({ message: err.message });
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script>
<div ng-app="App" ng-controller="MyCtrl">
  <button ng-click="clicked()">Make Error</button>
  <div>Errors:</div>
  <div ng-repeat="item in notifications">{{item}}</div>
</div>

为了比较,这里是错误的(具有循环依赖):

angular.module("App", [])
.factory("notifications", function($rootScope) {
  $rootScope.notifications = [];
  function showMessage(msg) {
    $rootScope.notifications.push(msg);
  }
  return { showMessage };
})
.factory("$exceptionHandler", function(notifications) {
  return function(e, cause) {
    notifications.showMessage({ message: err.message });
  };
})
.controller("MyCtrl", function($scope) {
  $scope.clicked = () => {
    throw new Error("Error made");
  };
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script>
<div ng-app="App" ng-controller="MyCtrl">
  <button ng-click="clicked()">Make Error</button>
  <div>Errors:</div>
  <div ng-repeat="item in notifications">{{item}}</div>
</div>