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图像处理—虚拟边缘介绍及使用方法
Dec 27 Javascript
jQuery阻止事件冒泡具体实现
Oct 11 Javascript
JS+CSS实现可拖拽的漂亮圆角特效弹出层完整实例
Feb 13 Javascript
DOM 高级编程
May 06 Javascript
在Node.js应用中使用Redis的方法简介
Jun 24 Javascript
jQuery实现的简洁下拉菜单导航效果代码
Aug 26 Javascript
js如何判断访问是来自搜索引擎(蜘蛛人)还是直接访问
Sep 14 Javascript
JavaScript 基础函数_深入剖析变量和作用域
May 18 Javascript
JS中的hasOwnProperty()和isPrototypeOf()属性实例详解
Aug 11 Javascript
实例讲解JavaScript截取字符串
Nov 30 Javascript
layer扩展打开/关闭动画的方法
Sep 23 Javascript
antd 表格列宽自适应方法以及错误处理操作
Oct 27 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
做一个有下拉功能的留言版
2006/10/09 PHP
PHP JSON格式数据交互实例代码详解
2011/01/13 PHP
如何通过Linux命令行使用和运行PHP脚本
2015/07/29 PHP
php基于CodeIgniter实现图片上传、剪切功能
2016/05/14 PHP
[原创]php正则删除img标签的方法示例
2017/05/27 PHP
php命名空间设计思想、用法与缺点分析
2019/07/17 PHP
Jquery 基础学习笔记
2009/05/29 Javascript
Javascript 面向对象 对象(Object)
2010/05/13 Javascript
分享8款优秀的 jQuery 加载动画和进度条插件
2012/10/24 Javascript
jQuery 事件的命名空间简单了解
2013/11/22 Javascript
鼠标选择动态改变网页背景颜色的JS代码
2013/12/10 Javascript
JS定时器实现数值从0到10来回变化
2016/12/09 Javascript
将鼠标焦点定位到文本框最后(代码分享)
2017/01/11 Javascript
jQuery弹出层插件popShow(改进版)用法示例
2017/01/23 Javascript
jQuery插件FusionCharts实现的MSBar3D图效果示例【附demo源码】
2017/03/23 jQuery
基于JavaScript 性能优化技巧心得(分享)
2017/12/11 Javascript
swiper移动端轮播插件(触碰图片之后停止轮播)
2017/12/28 Javascript
详解Javascript中new()到底做了些什么?
2018/03/29 Javascript
JS实现的缓冲运动效果示例
2018/04/30 Javascript
jQuery插件实现弹性运动完整示例
2018/07/07 jQuery
vue+vuex+json-seiver实现数据展示+分页功能
2019/04/11 Javascript
分析python服务器拒绝服务攻击代码
2014/01/16 Python
Python类属性与实例属性用法分析
2015/05/09 Python
Python基于分水岭算法解决走迷宫游戏示例
2017/09/26 Python
Python3用tkinter和PIL实现看图工具
2018/06/21 Python
Python设计模式之模板方法模式实例详解
2019/01/17 Python
python实现控制COM口的示例
2019/07/03 Python
Python爬取豆瓣视频信息代码实例
2019/11/16 Python
python实现差分隐私Laplace机制详解
2019/11/25 Python
Python基于yield遍历多个可迭代对象
2020/03/12 Python
纯CSS3代码实现switch滑动开关按钮效果
2016/08/30 HTML / CSS
好药师网上药店:安全合法的网上药品零售药房
2017/02/15 全球购物
介绍一下如何利用路径遍历进行攻击及如何防范
2014/01/19 面试题
道德演讲稿
2014/05/21 职场文书
党支部先进事迹材料
2014/12/24 职场文书
java如何实现socket连接方法封装
2021/09/25 Java/Android