AngualrJS中每次$http请求时的一个遮罩层Directive


Posted in Javascript onJanuary 26, 2016

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

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

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

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

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

<div data-my-overlay>
<br/><img src="spinner.gif" />   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 ,希望对大家有所帮助。

Javascript 相关文章推荐
javascript 获取网页参数系统
Jul 19 Javascript
javascript中RegExp保留小数点后几位数的方法分享
Aug 13 Javascript
jquery实现保存已选用户
Jul 21 Javascript
js中的事件捕捉模型与冒泡模型实例分析
Jan 10 Javascript
JS设置cookie、读取cookie、删除cookie
Apr 17 Javascript
Node.js重新刷新session过期时间的方法
Feb 04 Javascript
BootStrap table使用方法分析
Nov 08 Javascript
vue-router 学习快速入门
Mar 01 Javascript
解决ionic和angular上拉加载的问题
Aug 03 Javascript
Angular-UI Bootstrap组件实现警报功能
Jul 16 Javascript
JS数组扁平化(flat)方法总结详解
Jun 24 Javascript
手写Spirit防抖函数underscore和节流函数lodash
Mar 22 Javascript
JavaScript html5 canvas画布中删除一个块区域的方法
Jan 26 #Javascript
HTML5游戏引擎LTweenLite实现的超帅动画效果(附demo源码下载)
Jan 26 #Javascript
jQuery form插件的使用之处理server返回的JSON, XML,HTML数据
Jan 26 #Javascript
JavaScript+html5 canvas绘制缤纷多彩的三角形效果完整实例
Jan 26 #Javascript
JavaScript+html5 canvas制作的百花齐放效果完整实例
Jan 26 #Javascript
JavaScript+html5 canvas绘制渐变区域完整实例
Jan 26 #Javascript
Javascript中匿名函数的调用与写法实例详解(多种)
Jan 26 #Javascript
You might like
ThinkPHP关联模型操作实例分析
2012/09/23 PHP
php smarty truncate UTF8乱码问题解决办法
2014/06/13 PHP
PHP实现根据图片色界在不同位置加水印的方法
2015/08/08 PHP
window.showModalDialog使用手册
2007/01/11 Javascript
学习js所必须要知道的一些
2007/03/07 Javascript
ExtJs扩展之GroupPropertyGrid代码
2010/03/05 Javascript
javascript笔记 String类replace函数的一些事
2011/09/22 Javascript
javascript 基础篇2 数据类型,语句,函数
2012/03/14 Javascript
javascript获取URL参数与参数值的示例代码
2013/12/20 Javascript
JS生成不重复随机数组的函数代码
2014/06/10 Javascript
JavaScript如何动态创建table表格
2020/08/02 Javascript
详细探究ES6之Proxy代理
2016/07/22 Javascript
微信小程序 定位到当前城市实现实例代码
2017/02/23 Javascript
jQuery中库的引用方法
2018/01/06 jQuery
angular 服务随记小结
2019/05/06 Javascript
laypage+SpringMVC实现后端分页
2019/07/27 Javascript
js实现移动端吸顶效果
2020/01/08 Javascript
[03:14]2014DOTA2西雅图国际邀请赛 EG战队巡礼
2014/07/07 DOTA
[01:51]DAC趣味视频-如何成为职业选手.mp4
2017/04/02 DOTA
[01:05:36]VP vs TNC Supermajor小组赛B组 BO3 第二场 6.2
2018/06/03 DOTA
python读取视频流提取视频帧的两种方法
2020/10/22 Python
python实现比较类的两个instance(对象)是否相等的方法分析
2019/06/26 Python
在Python中实现函数重载的示例代码
2019/12/12 Python
解决Keras使用GPU资源耗尽的问题
2020/06/22 Python
HTML5 图片预加载的示例代码
2020/03/25 HTML / CSS
维珍澳洲航空官网:Virgin Australia
2017/09/08 全球购物
荷兰街头时尚之家:Funkie House
2019/03/18 全球购物
意大利在线高尔夫商店:Online Golf
2021/03/09 全球购物
专科毕业生求职简历的自我评价
2013/10/12 职场文书
先进个人事迹材料
2014/01/25 职场文书
工作说明书范文
2014/05/07 职场文书
消防志愿者活动方案
2014/08/23 职场文书
小学生竞选班干部演讲稿(5篇)
2014/09/12 职场文书
python调用ffmpeg命令行工具便捷操作视频示例实现过程
2021/11/01 Python
Python中的嵌套循环详情
2022/03/23 Python
postgresql中如何执行sql文件
2023/05/08 PostgreSQL