我尝试使用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
工厂,但得到了同样的错误。
答案 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>