循环依赖 - 如何解决和避免

时间:2016-02-22 14:16:50

标签: angularjs

我刚刚在我的一个模块中添加了一个http响应拦截器,并遇到了循环依赖问题:

  

未捕获错误:[$ injector:cdep]找到循环依赖项:$ http< -   $ templateFactory< - $ view< - $ state< - responseInterceptor< - $ http< -   $ translateStaticFilesLoader

代码

(function() {
  'use strict';

  angular
    .module('app.core', ['ngAnimate',
      'ngSanitize',
      'ngResource',
      'ui.bootstrap',
      'ui.router.tabs',
      'scDateTime',
      'schemaForm',
      'ui.validate',
      'ngStorage',
      'ngMaterial',
      'pascalprecht.translate',
      'ui.router'
    ])
    .factory('responseInterceptor', responseInterceptor)
    .config(httpProviderConfig);

  responseInterceptor.$inject = ['$q', '$rootScope', '$state'];
  function responseInterceptor($q, $rootScope, $state){
    return {
      responseError: function(response) {
        $rootScope.showSpinner = false;
        if(response.status === 401){
          $state.go('login');
        }
        return $q.reject(response);

      }
    }
  }

  httpProviderConfig.$inject = ['$httpProvider'];
  function httpProviderConfig($httpProvider){
    $httpProvider.interceptors.push('responseInterceptor');
  }
})();

我可以使用$injector.get()来解决此问题,而不是检索实例:

  responseInterceptor.$inject = ['$q', '$rootScope', '$injector'];
  function responseInterceptor($q, $rootScope, $injector){
    return {
      responseError: function(response) {
        $rootScope.showSpinner = false;
        if(response.status === 401){
          $injector.get('$state').go('login');
        }
        return $q.reject(response);

      }
    }
  }

虽然这有效,但我宁愿尝试解决问题的根源。

根据错误判断,我认为这是由app.core模块上的以下配置引起的

(function() {
  'use strict';

  angular.module('app.core').config(translateProviderConfig);

  translateProviderConfig.$inject = ['$translateProvider'];

  function translateProviderConfig($translateProvider) {
    $translateProvider.useStaticFilesLoader({
      prefix: 'assets/locale/',
      suffix: '.json'
    });
    $translateProvider.preferredLanguage('en_gb');
    return $translateProvider.useSanitizeValueStrategy('sanitize');
  }
})();

所以我不确定接下来要做什么,使用$injector.get()是否有效,或者这表明存在其他问题,其中包括依赖关系,例如重复?

1 个答案:

答案 0 :(得分:1)

如果您可以重新设计代码以避免它,您应该。但是,如果我正确地读取了您的代码,那么在几乎无法避免循环引用的情况下进行注入。事实上,我第一次发现这种“黑客”是我做一些非常相似的事情。 (在http调用期间建立等待状态。)

我要提到的唯一警告是你需要在需要它的方法中执行$ inject.get()而不是在方法所在的对象的构造函数中,或者你将继续获得循环参考