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 相关文章推荐
ie 7/8不支持trim的属性的解决方案
May 23 Javascript
Javascript学习笔记之 函数篇(一) : 函数声明和函数表达式
Jun 24 Javascript
javascript排序函数实现数字排序
Jun 26 Javascript
JQuery实现左右滚动菜单特效
Sep 28 Javascript
分享jQuery插件的学习笔记
Jan 14 Javascript
利用JavaScript阻止表单提交的两种方法
Aug 11 Javascript
正则验证小数点后面只能有两位数的方法
Feb 28 Javascript
Angular.js实现动态加载组件详解
May 28 Javascript
基于jquery实现左右上下移动效果
May 02 jQuery
在LayUI图片上传中,解决由跨域问题引起的请求接口错误的方法
Sep 24 Javascript
js里面的变量范围分享
Jul 18 Javascript
如何利用JS将手机号中间四位变成*号
Sep 29 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 在线打包_支持子目录
2008/06/28 PHP
PHP MYSQL乱码问题,使用SET NAMES utf8校正
2009/11/30 PHP
跟我学Laravel之快速入门
2014/10/15 PHP
关于php中一些字符串总结
2016/05/05 PHP
创建公共调用 jQuery Ajax 带返回值
2012/08/01 Javascript
DWZ刷新dialog解决方法
2013/03/03 Javascript
JQuery判断子iframe何时加载完成解决方案
2013/08/20 Javascript
jQuery实现的简洁下拉菜单导航效果代码
2015/08/26 Javascript
easyui-edatagrid.js实现回车键结束编辑功能的实例
2017/04/12 Javascript
详解webpack 如何集成第三方js库
2017/06/29 Javascript
jQuery UI 实例讲解 - 日期选择器(Datepicker)
2017/09/18 jQuery
vue项目中使用百度地图的方法
2018/06/08 Javascript
移动端吸顶fixbar的解决方案详解
2019/07/17 Javascript
[05:08]DOTA2-DPC中国联赛3月6日Recap集锦
2021/03/11 DOTA
python使用PyGame模块播放声音的方法
2015/05/20 Python
Python函数中*args和**kwargs来传递变长参数的用法
2016/01/26 Python
深入理解Python中range和xrange的区别
2017/11/26 Python
单利模式及python实现方式详解
2018/03/20 Python
Python企业编码生成系统总体系统设计概述
2019/07/26 Python
python 实现图片上传接口开发 并生成可以访问的图片url
2019/12/18 Python
python实现猜数游戏
2020/03/27 Python
python中id函数运行方式
2020/07/03 Python
python中的插入排序的简单用法
2021/01/19 Python
详解Python中的Lock和Rlock
2021/01/26 Python
HTML5上传文件显示进度的实现代码
2012/08/30 HTML / CSS
德国2018年度最佳在线药房:Bodfeld Apotheke
2019/11/04 全球购物
销售会计岗位职责
2014/03/15 职场文书
办理房产过户的委托书
2014/09/14 职场文书
农村党支部书记四风问题个人对照检查材料
2014/09/21 职场文书
教师党的群众路线学习心得体会
2014/11/04 职场文书
表扬稿范文
2015/01/17 职场文书
大队委员竞选稿
2015/11/20 职场文书
利用Python判断你的密码难度等级
2021/06/02 Python
VS2019连接MySQL数据库的过程及常见问题总结
2021/11/27 MySQL
动画电影《擅长捉弄人的高木同学》6月10日上映!
2022/03/20 日漫
Apache Pulsar结合Hudi构建Lakehouse方案分析
2022/03/31 Servers