将 $state (ui-router) 注入 $http 拦截器会导致循环依赖 [英] Injecting $state (ui-router) into $http interceptor causes circular dependency
问题描述
我想要达到的目标
如果 $http 请求返回 401 错误,我想转换到某个状态(登录).因此,我创建了一个 $http 拦截器.
I would like to to transition to a certain state (login) in case an $http request returns a 401 error. I have therefore created an $http interceptor.
问题
当我尝试将 '$state' 插入拦截器时,我得到了循环依赖.为什么以及如何修复它?
When I am trying to insert '$state' into the interceptor I get a circular dependency. Why and how do i fix it?
代码
//Inside Config function
var interceptor = ['$location', '$q', '$state', function($location, $q, $state) {
function success(response) {
return response;
}
function error(response) {
if(response.status === 401) {
$state.transitionTo('public.login');
return $q.reject(response);
}
else {
return $q.reject(response);
}
}
return function(promise) {
return promise.then(success, error);
}
}];
$httpProvider.responseInterceptors.push(interceptor);
推荐答案
The Fix
使用 $injector
服务获取对 $state
服务的引用.
The Fix
Use the $injector
service to get a reference to the $state
service.
var interceptor = ['$location', '$q', '$injector', function($location, $q, $injector) {
function success(response) {
return response;
}
function error(response) {
if(response.status === 401) {
$injector.get('$state').transitionTo('public.login');
return $q.reject(response);
}
else {
return $q.reject(response);
}
}
return function(promise) {
return promise.then(success, error);
}
}];
$httpProvider.responseInterceptors.push(interceptor);
原因
angular-ui-router 注入 $http
服务作为对 $TemplateFactory
的依赖,然后在调度拦截器时在 $httpProvider
自身内创建对 $http
的循环引用.
The Cause
angular-ui-router injects the $http
service as a dependency into $TemplateFactory
which then creates a circular reference to $http
within the $httpProvider
itself upon dispatching the interceptor.
如果您尝试像这样将 $http
服务直接注入拦截器,则会抛出相同的循环依赖异常.
The same circular dependency exception would be thrown if you attempt to inject the $http
service directly into an interceptor like so.
var interceptor = ['$location', '$q', '$http', function($location, $q, $http) {
关注点分离
循环依赖异常可能表明您的应用程序中存在可能导致稳定性问题的混合问题.如果您发现自己有此异常,您应该花时间查看您的架构,以确保避免任何最终引用自身的依赖项.
Separation of Concerns
Circular dependency exceptions can indicate that there is a mixing of concerns within your application which could cause stability issues. If you find yourself with this exception you should take the time to look at your architecture to ensure you avoid any dependencies that end up referencing themselves.
我同意下面的回答,即使用 $injector
直接获取对所需服务的引用并不理想,可以被视为一种反模式.
I agree with the answer below that using the $injector
to directly get a reference to the desired service is not ideal and could be considered an anti pattern.
发出事件是一种更加优雅且解耦的解决方案.
Emitting an event is a much more elegant and also decoupled solution.
这篇关于将 $state (ui-router) 注入 $http 拦截器会导致循环依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!