找到循环依赖:$ http < - $ templateFactory < - $ view < - $ state

Mr.*_*rth 34 angularjs angular-routing angular-ui-router

我有一个当前的401检查,我正在使用$ location运行正常.但是我想将它交换到$ state并使用ui-router代替.当我这样做时,我得到一个错误代码:

Circular dependency found: $http <- $templateFactory <- $view <- $state <- authHttpResponseInterceptor <- $http <- $compile
Run Code Online (Sandbox Code Playgroud)

当我检查某些路径并且不允许登录用户查看它时,我当前的代码看起来很好:

  /* Look for 401 auth errors and then redirect */
  .factory('authHttpResponseInterceptor',['$q','$location', function($q,$location) {

      return {
          response: function(response){
              if (response.status === 401) {
              }

              return response || $q.when(response);
          },
          responseError: function(rejection) {
              var reservedPaths = ['/','/login','/connect','/event'];
              if (rejection.status === 401 && _.contains(reservedPaths,$location.path().trim())) {
                  $location.path('/welcome');

              }
              return $q.reject(rejection);
          }
      };
  }])
  .config(['$httpProvider',function($httpProvider) {
      //Http Intercpetor to check auth failures for xhr requests
      $httpProvider.interceptors.push('authHttpResponseInterceptor');
  }]);
Run Code Online (Sandbox Code Playgroud)

我添加的代码如下:

  /* Look for 401 auth errors and then redirect */
  .factory('authHttpResponseInterceptor',['$q','$location', **'$state',** function($q,$location, **$state**) {

      return {
          response: function(response){
              if (response.status === 401) {
              }

              return response || $q.when(response);
          },
          responseError: function(rejection) {
              var reservedPaths = ['/','/mycube','/connect','/event'];
              if (rejection.status === 401 && _.contains(reservedPaths,$location.path().trim())) {
                  **$state.go('home');**

              }
              return $q.reject(rejection);
          }
      };
  }])
  .config(['$httpProvider',function($httpProvider) {
      //Http Intercpetor to check auth failures for xhr requests
      $httpProvider.interceptors.push('authHttpResponseInterceptor');
  }]);
Run Code Online (Sandbox Code Playgroud)

为什么添加状态会导致此问题,当它与位置正常工作?

aar*_*son 78

似乎$ state服务导致与$ http服务的循环依赖.这可能是因为templateFactory(请参阅https://github.com/angular-ui/ui-router/blob/master/src/templateFactory.js)除了使用$ http服务注入之外拦截器本身由$ http服务组成.

要解决此循环依赖性问题,可以使用$ injector服务将$ state服务连接到拦截器.查看修订后的代码:

/* Look for 401 auth errors and then redirect */
module.factory('authHttpResponseInterceptor', ['$q','$location', '$injector', function($q, $location, $injector) {
    return {
        response: function(response){
            if (response.status === 401) {
            }

            return response || $q.when(response);
        },
        responseError: function(rejection) {
            var reservedPaths = ['/', '/mycube', '/connect', '/event'];
            if (rejection.status === 401 && _.contains(reservedPaths, $location.path().trim())) {
                var stateService = $injector.get('$state');
                stateService.go('home');
            }
            return $q.reject(rejection);
        }
    };
}]);
Run Code Online (Sandbox Code Playgroud)

您可以在此处了解有关$ injector服务的更多信息:https://docs.angularjs.org/api/auto/service/ $ injector

重要

我建议使用状态更改事件(请参阅https://github.com/angular-ui/ui-router/wiki#state-change-events)使用$ stateChangeError查看错误并检查401返回的错误.

  • 真棒黑客!注意:我尝试在工厂的第一行上调用循环依赖的注入器,但仍然出错.如果有其他人遇到这种情况,请确保延迟获取服务,直到在request/response/responseError/etc函数内部(如提供的示例中) - 这应该可以解决问题. (4认同)