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 相关文章推荐
SWFObject Flash js调用类
Jul 08 Javascript
体验js中splice()的强大(插入、删除或替换数组的元素)
Jan 16 Javascript
第一篇初识bootstrap
Jun 21 Javascript
AngularJS入门教程之链接与图片模板详解
Aug 19 Javascript
DOM 事件的深入浅出(二)
Dec 05 Javascript
JavaScript装饰器函数(Decorator)实例详解
Mar 30 Javascript
JS实现上传图片实时预览功能
May 22 Javascript
Vue 使用 Mint UI 实现左滑删除效果CellSwipe
Apr 27 Javascript
Vue拖拽组件开发实例详解
May 11 Javascript
JS中min函数实例讲解
Feb 18 Javascript
node.js中express模块创建服务器和http模块客户端发请求
Mar 06 Javascript
bootstrap table.js动态填充单元格数据的多种方法
Jul 18 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
PHP数据缓存技术
2007/02/14 PHP
PHP基于IMAP收取邮件的方法示例
2017/08/07 PHP
PHP开发api接口安全验证操作实例详解
2020/03/26 PHP
jquery动画4.升级版遮罩效果的图片走廊--带自动运行效果
2012/08/24 Javascript
HTML上传控件取消选择
2013/03/06 Javascript
js使用for循环及if语句判断多个一样的name
2014/09/09 Javascript
node.js中的url.format方法使用说明
2014/12/10 Javascript
JS自定义对象实现Java中Map对象功能的方法
2015/01/20 Javascript
jQuery仿360导航页图标拖动排序效果代码分享
2015/08/24 Javascript
angularjs学习笔记之简单介绍
2015/09/26 Javascript
Angularjs结合Bootstrap制作的一个TODO List
2016/08/18 Javascript
微信小程序授权获取用户详细信息openid的实例详解
2017/09/20 Javascript
JS获取日期的方法实例【昨天,今天,明天,前n天,后n天的日期】
2017/09/28 Javascript
vue解决使用webpack打包后keep-alive不生效的方法
2018/09/01 Javascript
node.js使用redis储存session的方法
2018/09/26 Javascript
Vue一个案例引发的递归组件的使用详解
2018/11/15 Javascript
JQuery判断radio单选框是否选中并获取值的方法
2019/01/17 jQuery
常见的在Python中实现单例模式的三种方法
2015/04/08 Python
用Python实现换行符转换的脚本的教程
2015/04/16 Python
Python小工具之消耗系统指定大小内存的方法
2018/12/03 Python
python中dict()的高级用法实现
2019/11/13 Python
python中Lambda表达式详解
2019/11/20 Python
matplotlib 对坐标的控制,加图例注释的操作
2020/04/17 Python
python爬虫构建代理ip池抓取数据库的示例代码
2020/09/22 Python
HTML5新增的标签和属性归纳总结
2018/05/02 HTML / CSS
Saks Fifth Avenue澳洲/亚太地区:萨克斯第五大道精品百货店
2019/06/09 全球购物
英国伦敦的睡衣品牌:Asceno
2019/10/06 全球购物
出纳的岗位职责
2013/11/09 职场文书
畜牧兽医本科生的自我评价
2014/03/03 职场文书
2014年党员自我剖析材料
2014/10/07 职场文书
2016年春季趣味运动会开幕词
2016/03/04 职场文书
子女赡养老人协议书
2016/03/23 职场文书
使用 JavaScript 制作页面效果
2021/04/21 Javascript
MySQL5.7并行复制原理及实现
2021/06/03 MySQL
使用springMVC所需要的pom配置
2021/09/15 Java/Android
SQL使用复合索引实现数据库查询的优化
2022/05/25 SQL Server