Подтвердить что ты не робот

Обнаружена круговая зависимость: $http <- $templateFactory <- $view <- $state

У меня есть текущая проверка 401, что я работаю с $location, которая работает нормально. Однако я бы хотел поменять его на $state и вместо этого использовать ui-router. Когда я это сделаю, я получаю код ошибки как:

Circular dependency found: $http <- $templateFactory <- $view <- $state <- authHttpResponseInterceptor <- $http <- $compile

Мой текущий код выглядит отлично, когда я проверяю определенные пути и не разрешаю пользователям просматривать их:

  /* 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');
  }]);

Код, который я добавил, выглядит следующим образом:

  /* 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');
  }]);

Почему добавление состояния вызывает эту проблему, когда она отлично работает с местоположением?

4b9b3361

Ответ 1

Похоже, что $state service приводит к циклической зависимости от службы $http. Это может быть вызвано тем, что templateFactory (см. https://github.com/angular-ui/ui-router/blob/master/src/templateFactory.js) вводится с помощью службы $http в дополнение к самому перехватчику, являющемуся состоящий из службы $http.

Чтобы обойти эту проблему с круговой зависимостью, вы можете использовать службу $инжектора, чтобы подключить $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);
        }
    };
}]);

Подробнее об услуге $injector вы можете узнать здесь: https://docs.angularjs.org/api/auto/service/ $injector

ВАЖНО

Я бы рекомендовал использовать события изменения состояния (см. https://github.com/angular-ui/ui-router/wiki#state-change-events) для просмотра ошибок с использованием $stateChangeError и проверки ошибки, возвращаемой с 401.

Ответ 2

Вот самое простое решение, которое я сделал, и это сработало. Внутри factory напишите:

var $http = $injector.get("$http");

а затем используйте $http, как обычно.

ПРИМЕЧАНИЕ: Если у вас нет $инжектора, доступного в вашем factory, просто введите его, следуя

.factory('authHttpResponseInterceptor',['$q','$location','$injector', function($q,$location,$injector) {
}])