将 $state (ui-router) 注入 $http 拦截器会导致循环依赖 [英] Injecting $state (ui-router) into $http interceptor causes circular dependency

查看:19
本文介绍了将 $state (ui-router) 注入 $http 拦截器会导致循环依赖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要达到的目标

如果 $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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆