AngualrJS中每次$http请求时的一个遮罩层Directive  更新时间:2016年01月26日 15:36:17   作者:Darren Ji   AngularJS是一款非常强大的前端MVC框架。接下来通过本文给大家介绍AngualrJS中每次$http请求时的一个遮罩层Directive,本文非常具有参考借鉴价值,特此分享供大家学习 AngularJS是一款非常强大的前端MVC框架。在AngualrJS中使用$http每次向远程API发送请求,等待响应,这中间有些许的等待过程。如何优雅地处理这个等待过程呢? 如果我们在等待过程中弹出一个遮罩层,会是一个比较优雅的做法。 这就涉及到了对$http的请求响应进行拦截了。请求的时候,弹出一个遮罩层,收到响应的时候把遮罩层隐藏。 其实,$httpProvider已经为我们提供了一个$httpProvider.interceptors属性,我们只需要把自定义的拦截器放到该集合中就可以了。 如何表现呢?大致是这样的:   Loading 显示加载的图片被包含在Directive中了,肯定会用到transclusion。 还涉及到一个遮罩层弹出延迟时间的问题,这个我们希望在config中通过API设置,所以,我们有必要创建一个provider,通过这个设置延迟时间。 $http请求响应遮罩层的Directive: (function(){ var myOverlayDirective =function($q, $timeout, $window, httpInterceptor, myOverlayConfig){ return { restrict: ‘EA’, transclude: true, scope: { myOverlayDelay: “@” }, template: ” + ” + ” + ” + ”, link: function(scope, element, attrs){ var overlayContainer = null, timePromise = null, timerPromiseHide = null, inSession = false, queue = [], overlayConfig = myOverlayConfig.getConfig(); init(); //初始化 function init(){ wireUpHttpInterceptor(); if(window.jQuery) wirejQueryInterceptor(); overlayContainer = document.getElementById(‘overlay-container’); } //自定义Angular的http拦截器 function wireUpHttpInterceptor(){ //请求拦截 httpInterceptor.request = function(config){ //判断是否满足显示遮罩的条件 if(shouldShowOverlay(config.method, config.url)){ processRequest(); } return config || $q.when(config); }; //响应拦截 httpInterceptor.response = function(response){ processResponse(); return response || $q.when(response); } //异常拦截 httpInterceptor.responseError = function(rejection){ processResponse(); return $q.reject(rejection); } } //自定义jQuery的http拦截器 function wirejQueryInterceptor(){ $(document).ajaxStart(function(){ processRequest(); }); $(document).ajaxComplete(function(){ processResponse(); }); $(document).ajaxError(function(){ processResponse(); }); } //处理请求 function processRequest(){ queue.push({}); if(queue.length == 1){ timePromise = $timeout(function(){ if(queue.length) showOverlay(); }, scope.myOverlayDelay ? scope.myOverlayDelay : overlayConfig.delay); } } //处理响应 function processResponse(){ queue.pop(); if(queue.length == 0){ timerPromiseHide = $timeout(function(){ hideOverlay(); if(timerPromiseHide) $timeout.cancel(timerPromiseHide); },scope.myOverlayDelay ? scope.myOverlayDelay : overlayConfig.delay); } } //显示遮罩层 function showOverlay(){ var w = 0; var h = 0; if(!$window.innerWidth){ if(!(document.documentElement.clientWidth == 0)){ w = document.documentElement.clientWidth; h = document.documentElement.clientHeight; } else { w = document.body.clientWidth; h = document.body. clientHeight; } }else{ w = $window.innerWidth; h = $window.innerHeight; } var content = docuemnt.getElementById(‘overlay-content’); var contetWidth = parseInt(getComputedStyle(content, ‘width’).replace(‘px’,”)); var contentHeight = parseInt(getComputedStyle(content, ‘height’).replace(‘px’,”)); content.style.top = h / 2 – contentHeight / 2 + ‘px’; content.style.left = w / 2 – contentWidth / 2 + ‘px’; overlayContainer.style.display = ‘block’; } function hideOverlay(){ if(timePromise) $timeout.cancel(timerPromise); overlayContainer.style.display = ‘none’; } //得到一个函数的执行结果 var getComputedStyle = function(){ var func = null; if(document.defaultView && document.defaultView.getComputedStyle){ func = document.defaultView.getComputedStyle; } else if(typeof(document.body.currentStyle) !== “undefined”){ func = function(element, anything){ return element[“currentStyle”]; } } return function(element, style){ reutrn func(element, null)[style]; } }(); //决定是否显示遮罩层 function shouldShowOverlay(method, url){ var searchCriteria = { method: method, url: url }; return angular.isUndefined(findUrl(overlayConfig.exceptUrls, searchCriteria)); } function findUrl(urlList, searchCriteria){ var retVal = undefined; angular.forEach(urlList, function(url){ if(angular.equals(url, searchCriteria)){ retVal = true; return false;//推出循环 } }) return retVal; } } } }; //配置$httpProvider var httpProvider = function($httpProvider){ $httpProvider.interceptors.push(‘httpInterceptor’); }; //自定义interceptor var httpInterceptor = function(){ return {}; }; //提供配置 var myOverlayConfig = function(){ //默认配置 var config = { delay: 500, exceptUrl: [] }; //设置延迟 this.setDelay = function(delayTime){ config.delay = delayTime; } //设置异常处理url this.setExceptionUrl = function(urlList){ config.exceptUrl = urlList; }; //获取配置 this.$get = function(){ return { getDelayTime: getDelayTime, getExceptUrls: getExceptUrls, getConfig: getConfig } function getDelayTime(){ return config.delay; } function getExeptUrls(){ return config.exceptUrls; } function getConfig(){ return config; } }; }; var myDirectiveApp = angular.module(‘my.Directive’,[]); myDirectiveApp.provider(‘myOverlayConfig’, myOverlayConfig); myDirectiveApp.factory(‘httpInterceptor’, httpInterceptor); myDirectiveApp.config(‘$httpProvider’, httpProvider); myDirectiveApp.directive(‘myOverlay’, [‘$q’, ‘$timeout’, ‘$window’, ‘httpInceptor’, ‘myOverlayConfig’, myOverlayDirective]); }()); 在全局配置中: (functioin(){ angular.module(‘customersApp’,[‘ngRoute’, ‘my.Directive’]) .config([‘$routeProvider, ‘myOverlayConfigProvider’, funciton($routeProvider, myOverlayConfigProvider){ … myOverlayConfigProvider.setDealy(100); myOverlayConfigProvider.setExceptionUrl({ method: ‘GET’, url: ” }); }]); }()); 以上所述是小编给大家分享的AngualrJS中每次$http请求时的一个遮罩层Directive ,希望对大家有所帮助。 您可能感兴趣的文章: 学习AngularJs:Directive指令用法(完整版) AngularJS中的Directive实现延迟加载 AngularJS入门心得之directive和controller通信过程 AngularJS中的Directive自定义一个表格 AngularJS directive返回对象属性详解 Angular 根据 service 的状态更新 directive JSP由浅入深(7)—— JSP Directives AngularJs directive详解及示例代码 Angularjs使用directive自定义指令实现attribute继承的方法详解 前端框架Vue.js中Directive知识详解 angularjs directive 相关文章 angular实现spa单页面应用实例 本篇文章主要介绍了angular实现spa单页面应用实例,小本篇文章是对单页面的一个简单的基本逻辑操作,这个方法可以搭建基本的单页面的逻辑结构。一起跟随小编过来看看吧 2017-07-07 Angular 容器部署的方法 这篇文章主要介绍了Angular 容器部署的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧 2018-04-04 Angularjs实现分页和分页算法的示例代码 分页是很多web应用都会用到的,本篇文章主要介绍了Angularjs实现分页和分页算法的示例代码,具有一定的参考价值,有兴趣的可以了解一下。 2016-12-12 三种AngularJS中获取数据源的方式 这篇文章主要介绍了三种AngularJS中获取数据源的方式,需要的朋友可以参考下 2016-02-02 Angular弹出模态框的两种方式 这篇文章主要介绍了Angular弹出模态框的两种方式,非常不错,具有参考借鉴价值,需要的朋友可以参考下 2017-10-10 AngularJS通过$http和服务器通信详解 相信大家都知道AngularJS是一个前端框架,实现了可交互式的页面,但是对于一个web应用,页面上进行展示的数据从哪里来,肯定需要服务端进行支持,那么AngularJS是如何同服务端进行交互的呢?通过这篇文章大家一起来看看吧。 2016-09-09 基于AngularJS拖拽插件ngDraggable.js实现拖拽排序功能 ngDraggable.js是一款比较简单实用的angularJS拖拽插件,借助于封装好的一些自定义指令,能够快速的进行一些拖拽应用开发。本文先从基本概念入手,给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友参考下吧 2019-04-04 初学者AngularJS的环境搭建过程 这篇文章主要介绍了初学者AngularJS的环境搭建过程,在文章给大家提到了Angular-cli的特性,大家一起看看吧 2017-10-10 angular.js中解决跨域问题的三种方式 跨域,前端开发中经常遇到的问题,下面这篇文章主要给大家介绍了关于angular.js中解决跨域问题的三种方式,文中介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面跟着小编一起来学习学习吧。 2017-07-07 AngularJS初始化静态模板详解 这篇文章主要为大家介绍了AngularJS初始化静态模板,AngularJS初始化静态模板有两种方式,一是通过ng-app来自动初始化模块,也可以通过angular.bootstrap(document, [module])手动启动应用,感兴趣的小伙伴们可以参考一下 2016-01-01 最新评论

AngularJS是一款非常强大的前端MVC框架。在AngualrJS中使用$http每次向远程API发送请求,等待响应,这中间有些许的等待过程。如何优雅地处理这个等待过程呢?

如果我们在等待过程中弹出一个遮罩层,会是一个比较优雅的做法。

这就涉及到了对$http的请求响应进行拦截了。请求的时候,弹出一个遮罩层,收到响应的时候把遮罩层隐藏。

其实,$httpProvider已经为我们提供了一个$httpProvider.interceptors属性,我们只需要把自定义的拦截器放到该集合中就可以了。

如何表现呢?大致是这样的:

<div data-my-overlay>
<br/><img src="spinner.gif" /> &nbsp;&nbsp;Loading
</div> 

显示加载的图片被包含在Directive中了,肯定会用到transclusion。

还涉及到一个遮罩层弹出延迟时间的问题,这个我们希望在config中通过API设置,所以,我们有必要创建一个provider,通过这个设置延迟时间。

$http请求响应遮罩层的Directive:

(function(){
var myOverlayDirective =function($q, $timeout, $window, httpInterceptor, myOverlayConfig){
return {
restrict: 'EA',
transclude: true,
scope: {
myOverlayDelay: "@"
},
template: '<div id="overlay-container" class="onverlayContainer">' +
'<div id="overlay-background" class="onverlayBackground"></div>' +
'<div id="onverlay-content" class="onverlayContent" data-ng-transclude>' +
'</div>' +
'</div>',
link: function(scope, element, attrs){
var overlayContainer = null,
timePromise = null,
timerPromiseHide = null,
inSession = false,
queue = [],
overlayConfig = myOverlayConfig.getConfig();
init();
//初始化
function init(){
wireUpHttpInterceptor();
if(window.jQuery) wirejQueryInterceptor();
overlayContainer = document.getElementById('overlay-container');
}
//自定义Angular的http拦截器
function wireUpHttpInterceptor(){
//请求拦截
httpInterceptor.request = function(config){
//判断是否满足显示遮罩的条件
if(shouldShowOverlay(config.method, config.url)){
processRequest();
}
return config || $q.when(config);
};
//响应拦截
httpInterceptor.response = function(response){
processResponse();
return response || $q.when(response);
}
//异常拦截
httpInterceptor.responseError = function(rejection){
processResponse();
return $q.reject(rejection);
}
}
//自定义jQuery的http拦截器
function wirejQueryInterceptor(){
$(document).ajaxStart(function(){
processRequest();
});
$(document).ajaxComplete(function(){
processResponse();
});
$(document).ajaxError(function(){
processResponse();
});
}
//处理请求
function processRequest(){
queue.push({});
if(queue.length == 1){
timePromise = $timeout(function(){
if(queue.length) showOverlay();
}, scope.myOverlayDelay ? scope.myOverlayDelay : overlayConfig.delay);
}
}
//处理响应
function processResponse(){
queue.pop();
if(queue.length == 0){
timerPromiseHide = $timeout(function(){
hideOverlay();
if(timerPromiseHide) $timeout.cancel(timerPromiseHide);
},scope.myOverlayDelay ? scope.myOverlayDelay : overlayConfig.delay);
}
}
//显示遮罩层
function showOverlay(){
var w = 0;
var h = 0;
if(!$window.innerWidth){
if(!(document.documentElement.clientWidth == 0)){
w = document.documentElement.clientWidth;
h = document.documentElement.clientHeight;
} else {
w = document.body.clientWidth;
h = document.body. clientHeight;
}
}else{
w = $window.innerWidth;
h = $window.innerHeight;
}
var content = docuemnt.getElementById('overlay-content');
var contetWidth = parseInt(getComputedStyle(content, 'width').replace('px',''));
var contentHeight = parseInt(getComputedStyle(content, 'height').replace('px',''));
content.style.top = h / 2 - contentHeight / 2 + 'px';
content.style.left = w / 2 - contentWidth / 2 + 'px';
overlayContainer.style.display = 'block';
}
function hideOverlay(){
if(timePromise) $timeout.cancel(timerPromise);
overlayContainer.style.display = 'none';
}
//得到一个函数的执行结果
var getComputedStyle = function(){
var func = null;
if(document.defaultView && document.defaultView.getComputedStyle){
func = document.defaultView.getComputedStyle;
} else if(typeof(document.body.currentStyle) !== "undefined"){
func = function(element, anything){
return element["currentStyle"];
}
}
return function(element, style){
reutrn func(element, null)[style];
}
}();
//决定是否显示遮罩层
function shouldShowOverlay(method, url){
var searchCriteria = {
method: method,
url: url
};
return angular.isUndefined(findUrl(overlayConfig.exceptUrls, searchCriteria));
}
function findUrl(urlList, searchCriteria){
var retVal = undefined;
angular.forEach(urlList, function(url){
if(angular.equals(url, searchCriteria)){
retVal = true;
return false;//推出循环
}
})
return retVal;
}
}
}
};
//配置$httpProvider
var httpProvider = function($httpProvider){
$httpProvider.interceptors.push('httpInterceptor');
};
//自定义interceptor
var httpInterceptor = function(){
return {};
};
//提供配置
var myOverlayConfig = function(){
//默认配置
var config = {
delay: 500,
exceptUrl: []
};
//设置延迟
this.setDelay = function(delayTime){
config.delay = delayTime;
}
//设置异常处理url
this.setExceptionUrl = function(urlList){
config.exceptUrl = urlList;
};
//获取配置
this.$get = function(){
return {
getDelayTime: getDelayTime, 
getExceptUrls: getExceptUrls,
getConfig: getConfig
}
function getDelayTime(){
return config.delay;
}
function getExeptUrls(){
return config.exceptUrls;
}
function getConfig(){
return config;
}
};
};
var myDirectiveApp = angular.module('my.Directive',[]);
myDirectiveApp.provider('myOverlayConfig', myOverlayConfig);
myDirectiveApp.factory('httpInterceptor', httpInterceptor);
myDirectiveApp.config('$httpProvider', httpProvider);
myDirectiveApp.directive('myOverlay', ['$q', '$timeout', '$window', 'httpInceptor', 'myOverlayConfig', myOverlayDirective]);
}()); 

在全局配置中:

(functioin(){
angular.module('customersApp',['ngRoute', 'my.Directive'])
.config(['$routeProvider, 'myOverlayConfigProvider', funciton($routeProvider, myOverlayConfigProvider){
...
myOverlayConfigProvider.setDealy(100);
myOverlayConfigProvider.setExceptionUrl({
method: 'GET',
url: ''
});
}]);
}());

以上所述是小编给大家分享的AngualrJS中每次$http请求时的一个遮罩层Directive ,希望对大家有所帮助。

您可能感兴趣的文章:

  • 学习AngularJs:Directive指令用法(完整版)
  • AngularJS中的Directive实现延迟加载
  • AngularJS入门心得之directive和controller通信过程
  • AngularJS中的Directive自定义一个表格
  • AngularJS directive返回对象属性详解
  • Angular 根据 service 的状态更新 directive
  • JSP由浅入深(7)—— JSP Directives
  • AngularJs directive详解及示例代码
  • Angularjs使用directive自定义指令实现attribute继承的方法详解
  • 前端框架Vue.js中Directive知识详解
张贴在3