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实例
Oct 31 Javascript
JavaScript中的值类型详细介绍
Dec 29 Javascript
js网页滚动条滚动事件实例分析
May 05 Javascript
JS中处理时间之setUTCMinutes()方法的使用
Jun 12 Javascript
JavaScript实现星级评分
Jan 12 Javascript
JS 组件系列之Bootstrap Table的冻结列功能彻底解决高度问题
Jun 30 Javascript
Textarea输入字数限制实例(兼容iOS&amp;安卓)
Jul 06 Javascript
vue2中的keep-alive使用总结及注意事项
Dec 21 Javascript
原生js实现公告滚动效果
Jan 10 Javascript
Three.JS实现三维场景
Dec 30 Javascript
详解@Vue/Cli 3 Invalid Host header 错误解决办法
Jan 02 Javascript
详解vuejs中执行npm run dev出现页面cannot GET/问题
Apr 26 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实现登陆验证码(类似条行码状)
2006/10/09 PHP
PHP接口并发测试的方法(推荐)
2016/12/15 PHP
yii框架无限极分类的实现方法
2017/04/08 PHP
浅谈Laravel核心解读之Console内核
2018/12/02 PHP
laravel model模型定义实现开启自动管理时间created_at,updated_at
2019/10/17 PHP
js parseInt(&quot;08&quot;)未指定进位制问题
2010/06/19 Javascript
关于页面嵌入swf覆盖div层的问题的解决方法
2014/02/11 Javascript
JS+CSS实现可拖动的弹出提示框
2015/02/16 Javascript
JS实现很酷的EMAIL地址添加功能实例
2015/02/28 Javascript
基于Css3和JQuery实现打字机效果
2015/08/11 Javascript
jquery获取form表单input元素值的简单实例
2016/05/30 Javascript
JS从一组数据中找到指定的单条数据的方法
2016/06/02 Javascript
利用nodejs监控文件变化并使用sftp上传到服务器
2017/02/18 NodeJs
jQuery基于cookie实现换肤功能实例
2017/10/14 jQuery
Angular实现双向折叠列表组件的示例代码
2017/11/21 Javascript
Vuex入门到上手教程
2018/06/20 Javascript
Vue使用Clipboard.JS在h5页面中复制内容实例详解
2019/09/03 Javascript
python操作日期和时间的方法
2014/03/11 Python
Python实现Mysql数据库连接池实例详解
2017/04/11 Python
Python加密方法小结【md5,base64,sha1】
2017/07/13 Python
python中set()函数简介及实例解析
2018/01/09 Python
VSCode下配置python调试运行环境的方法
2018/04/06 Python
Python 实现将某一列设置为str类型
2020/07/14 Python
利用CSS3 动画 绘画 圆形动态时钟
2018/03/20 HTML / CSS
Trip.com香港网站:Ctrip携程旗下,全球最大的网上旅游社之一
2016/08/01 全球购物
英国著名音像制品和图书游戏购物网站:Zavvi
2016/08/04 全球购物
Darphin迪梵官网: 来自巴黎,植物和精油调制的护肤品牌
2016/10/11 全球购物
英国高级百货公司:Harvey Nichols
2017/01/29 全球购物
大专毕业生简历的自我评价
2013/10/20 职场文书
客服工作职责
2013/12/11 职场文书
职业生涯规划设计步骤
2014/01/12 职场文书
学雷锋演讲稿汇总
2014/05/10 职场文书
好习惯伴我成长演讲稿
2014/05/21 职场文书
英语教育专业毕业生求职信
2014/08/28 职场文书
成都人事代理协议书
2014/10/25 职场文书
教你做个可爱的css滑动导航条
2021/06/15 HTML / CSS