AngularJS 拦截器实现全局$http请求loading效果
日常项目开发中,当前端需要和后端进行数据交互时,为了友好的UI效果,一般都会在前端加个loading的状态提示(包括进度条或者icon显示),数据传输或交互完成之后,再隐藏/删除loading提示。
一般简单的做法就是在每个请求的业务逻辑前添加/显示loading,交互完成再删除/隐藏loading。
但是这样代码重复度高,每个请求的地方都需要编写一遍,比较繁琐。对开发人员来说,write less,do more!最好不过了,可以避免自己漏写等人为的不确定错误。
为此,我们可以利用angularjs拦截器,来实现全局的优化方案。
var myApp = angular.module('myApp', []); myApp.config(["$httpProvider", function ($httpProvider) { $httpProvider.interceptors.push('myInterceptor'); }]); //loading myApp.factory('myInterceptor', ["$rootScope", function ($rootScope) { var timestampMarker = { request: function (config) {
//start $rootScope.loading = true; return config; }, response: function (response) {
//end $rootScope.loading = false; return response; } }; return timestampMarker; }]);
什么是拦截器–What are Interceptors?
Interceptor(拦截器)在服务端框架中属于一种比较常见的机制。拦截器提供了一种机制可以使开发者可以定义在一个action(动作)执行的前后执行的代码,这些代码可以是在一个action执行前阻止其执行的代码,也可以是修改目标动作某些行为的代码.(在AOP(Aspect-Oriented Programming)中拦截器用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。
$http服务中的拦截器
查看API或是源码我们可以发现,Angular的实现中通过 httpProvider提供了一个名为interceptors的数组.这个数组接受拦截器服务注册,通过过程次的注册最终会形成拦截器链.这样每次在调用http服务的时候,angular都会通过我们定义的拦截点(切面)进行相应的Ajax动作修改.
Angular中如何声明一个拦截器
//Interceptor declaration module.factory('httpInterceptor', ['$log', function($log) { $log.debug('$log is here to show you that this is a regular factory with injection'); return { // do something }; }]);
如何将声明的拦截器注册到$http服务中
// Add the interceptor to $httpProvider.interceptors module.config(['$httpProvider', function($httpProvider) { $httpProvider.interceptors.push('httpInterceptor'); }]);
通过上面的简单两个步骤,我们基本就完成了http服务的拦截器编写与添加.但是上面的代码片段并不能实际使用,要想真正的实现拦截操作,我们还需要遵循http服务暴露出来的可以进行拦截的点进行相关的代码编写.
$httpProvider暴露了那些可以拦截的点?
-
request : request方法可以实现拦截请求: 该方法会在 http发送请求到服务器之前执行,因此我们可以在该方法的视线中修改配置或做其他的操作。该方法接收请求配置对象(requestconfigurationobject)作为参数,然后必须返回配置对象或者promis