我希望能够设置一个AngularJS http拦截器,它将设置$rootScope.loading为true或false取决于当前是否正在进行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)
您只能在 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
| 归档时间: |
|
| 查看次数: |
13897 次 |
| 最近记录: |