webentwicklung-frage-antwort-db.com.de

Zirkulare Abhängigkeit gefunden: $ http <- $ templateFactory <- $ view <- $ state

Ich habe einen aktuellen 401-Check, dass ich mit $ location arbeite, was einwandfrei funktioniert. Ich würde es jedoch gerne auf $ state umstellen und stattdessen den ui-router verwenden. Wenn ich dies tue, bekomme ich einen Fehlercode als:

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

Mein momentaner Code sieht gut aus, da ich bestimmte Pfade überprüfe und keinen angemeldeten Benutzern erlauben, sie anzuzeigen:

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

Der Code, den ich hinzugefügt habe, lautet wie folgt:

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

Warum sollte dieses Problem durch Hinzufügen von Status hervorgerufen werden, wenn es mit dem Standort gut funktioniert? 

35

Es scheint, dass der $ state-Dienst zu einer zirkulären Abhängigkeit mit dem $ http-Dienst führt. Dies kann durch die Tatsache verursacht werden, dass die templateFactory (siehe https://github.com/angular-ui/ui-router/blob/master/src/templateFactory.js ) mit dem $ http-Dienst injiziert wird zusätzlich zum Interceptor selbst mit dem $ http-Service.

Um dieses zyklische Abhängigkeitsproblem zu umgehen, können Sie den $ state-Dienst mit dem $ injector-Dienst an Ihren Interceptor anschließen. Siehe den überarbeiteten Code:

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

Mehr über den $ injector-Service erfahren Sie hier: https://docs.angularjs.org/api/auto/service/ $ injector

WICHTIG

Ich würde die Verwendung der Zustandsänderungsereignisse (siehe https://github.com/angular-ui/ui-router/wiki#state-change-events ) empfehlen, um auf Fehler zu achten, die $ stateChangeError verwenden, und den zurückgegebenen Fehler zu überprüfen von der 401.

76
aaronroberson

Hier ist die einfachste Lösung, die ich gemacht habe und es hat funktioniert. In der Fabrik schreiben Sie:

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

und dann $http wie gewohnt verwenden.

HINWEIS: Wenn in Ihrer Fabrik kein $ Injektor verfügbar ist, spritzen Sie ihn einfach wie folgt ein

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