在httpIntercept上设置rootScope变量

JP.*_*JP. 6 angularjs

我希望能够设置一个AngularJS http拦截器,它将设置$rootScope.loadingtruefalse取决于当前是否正在进行AJAX请求.

到目前为止,我已将以下内容放在一起:

angular.module('myApp')
.config(function ($httpProvider) {
  $httpProvider.responseInterceptors.push('loadingInterceptor');

  var loadingFunction = function (data, headersGetter) {
      $rootScope.loading = true

      return data;
  };
  $httpProvider.defaults.transformRequest.push(loadingFunction);
})
.factory('loadingInterceptor', function ($q, $window, $rootScope) {
    return function (promise) {
        return promise.then(function (response) {
            $rootScope.loading = false;
            return response;

        }, function (response) {
            $rootScope.loading = false;
            return $q.reject(response);
        });
    };
});
Run Code Online (Sandbox Code Playgroud)

但是我无法注入$rootScope配置块,所以$rootScope.loading当HTTP请求开始时我无法设置变量.

我在这里错过了什么吗?我该怎么做?

小智 13

responseInterceptors已被弃用http://docs.angularjs.org/api/ng.$http.我增强了前面的例子:

app.factory('myHttpInterceptor', ['$q', '$rootScope', '$injector',
    function ($q, $rootScope, $injector) {
        $rootScope.showSpinner = false;
        $rootScope.http = null;
        return {
            'request': function (config) {
                $rootScope.showSpinner = true;
                return config || $q.when(config);
            },
            'requestError': function (rejection) {
                $rootScope.http = $rootScope.http || $injector.get('$http');
                if ($rootScope.http.pendingRequests.length < 1) {
                    $rootScope.showSpinner = false;
                }
                if (canRecover(rejection)) {
                    return responseOrNewPromise
                }
                return $q.reject(rejection);
            },
            'response': function (response) {
                $rootScope.http = $rootScope.http || $injector.get('$http');
                if ($rootScope.http.pendingRequests.length < 1) {
                    $rootScope.showSpinner = false;
                }
                return response || $q.when(response);
            },
            'responseError': function (rejection) {
                $rootScope.http = $rootScope.http || $injector.get('$http');
                if ($rootScope.http.pendingRequests.length < 1) {
                    $rootScope.showSpinner = false;
                }
                if (canRecover(rejection)) {
                    return responseOrNewPromise
                }
                return $q.reject(rejection);
            }
        }
    }
]);
Run Code Online (Sandbox Code Playgroud)

你可以这样使用工厂:

app.config(function ($httpProvider) {
    $httpProvider.interceptors.push('myHttpInterceptor');
});
Run Code Online (Sandbox Code Playgroud)


joa*_*mbl 3

您只能在 module.config 中插入提供程序,但无论如何您都不应该在默认转换器中执行此操作,您应该在拦截器中执行此操作(就像设置 load = false 时所做的那样)。

可能有多个请求同时进行。像这样的事情可能会起作用:

angular.module('myApp')
  .config(function ($httpProvider) {
    $httpProvider.responseInterceptors.push(function ($rootScope) {
      $rootScope.numLoadings = 0;
      $rootScope.loading = false;
      return function (promise) {
        $rootScope.numLoadings++;
        $rootScope.loading = true;
        // make sure the loading screen is visible
        var hide = function (r) {
          if ((--$rootScope.numLoadings)===0){
            //console.log('hide the loading screen');
            $rootScope.loading = false;
          }
          return r;
        };
        return promise.then(hide, hide);
      };
    });
  });
Run Code Online (Sandbox Code Playgroud)

当然,您不必将 numLoadings 放在根范围中,我只是将其放在此处:http://plnkr.co/edit/32Mh9UOS3Z4vnOtrH9aR ?p=preview