[英]Angular - Circular dependency found when using ngNotificationsBar
I try to use ng-notifications-bar module, I have code like this: 我尝试使用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});
};
}]);
but got error: 但出现错误:
[$injector:cdep] Circular dependency found: $rootScope <- notifications <- $exceptionHandler <- $rootScope <- $timeout <- $$rAF <- $mdGesture [$ injector:cdep]发现循环依赖项:$ rootScope <-通知<-$ exceptionHandler <-$ rootScope <-$ timeout <-$$ rAF <-$ mdGesture
I've tried to modify the library to use $injector
to get $timeout and $rootScope but that didn't help also tried to use $injector
to get notifications
in $exceptionHandler
factory but got the same error. 我试图修改该库以使用$injector
来获取$ timeout和$ rootScope,但这也无济于事,还试图使用$injector
来获取$exceptionHandler
工厂中的notifications
,但出现了相同的错误。
Pretty poor design from angular it looks on this one. 从角度来看,这是一个很差的设计。 You can't inject $rootScope
in any form into $exceptionHandler
due to the dependency. 由于依赖关系,您不能以任何形式将$rootScope
注入$exceptionHandler
。
You can use $injector
to get around these kinds of (out-of-your-hands) dependency problems, you just need to make sure that the injected module is used inside the return function to ensure that at the time of calling .get()
the dependent module has actually loaded. 您可以使用$injector
来解决这类(无法使用的)依赖关系问题,您只需要确保在return函数内部使用注入的模块即可确保在调用.get()
相关模块已实际加载。 For example: 例如:
// won't not be available here
var rootScope = $injector.get('$rootScope');
return function(exception, cause) {
// will be available here
var rootScope = $injector.get('$rootScope');
};
This is because $injector
is used to grab the dependency at run time. 这是因为$injector
用于在运行时获取依赖项。
There is a nice clean object-oriented design to avoid circular dependencies: use the dependency inversion principle . 有一个很好的干净的面向对象设计可以避免循环依赖:使用依赖反转原理 。 Create a generic service to which you can attach handlers, and set it up from a run
block. 创建可以将处理程序附加到的常规服务,然后从run
块对其进行设置。 Basically all the other solutions suggest something similar, but with using global variables outside of angular, or bypassing the automatic dependency injection. 基本上所有其他解决方案都提出了类似的建议,但使用了超出角度的全局变量或绕过了自动依赖项注入。
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>
For comparison, here is the wrong one (with the circular dependency): 为了进行比较,这是错误的(具有循环依赖性):
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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.