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 相关文章推荐
js遍历、动态的添加数据的小例子
Jun 22 Javascript
js对文章内容进行分页示例代码
Mar 05 Javascript
JavaScript设计模式之外观模式介绍
Dec 28 Javascript
BootStrap table删除指定行的注意事项(笔记整理)
Feb 05 Javascript
addeventlistener监听scroll跟touch(实例讲解)
Aug 04 Javascript
详解解决Vue相同路由参数不同不会刷新的问题
Oct 12 Javascript
详解angularjs跨页面传参遇到的一些问题
Nov 01 Javascript
vue 中使用 watch 出现了如下的报错的原因分析
May 21 Javascript
详解vue 自定义组件使用v-model 及探究其中原理
Oct 11 Javascript
如何在Node和浏览器控制台中打印彩色文字
Jan 09 Javascript
Vue父子组件传值的一些坑
Sep 16 Javascript
vue el-table实现递归嵌套的示例代码
Aug 14 Vue.js
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
上海地方志办公室-上海电子仪表工业志
2021/03/04 无线电
PHP制作图型计数器的例子
2006/10/09 PHP
Ajax+PHP实现的分类列表框功能示例
2019/02/11 PHP
TP5框架model常见操作示例小结【增删改查、聚合、时间戳、软删除等】
2020/04/05 PHP
asp批量修改记录的代码
2008/06/25 Javascript
对 jQuery 中 data 方法的误解分析
2014/06/18 Javascript
Egret引擎开发指南之创建项目
2014/09/03 Javascript
基于jquery的文字向上跑动类似跑马灯的效果
2014/09/22 Javascript
JavaScript简单修改窗口大小的方法
2015/08/03 Javascript
基于JS实现新闻列表无缝向上滚动实例代码
2016/01/22 Javascript
如何让一个json文件显示在表格里【实现代码】
2016/05/09 Javascript
JS+HTML5手机开发之滚动和惯性缓动实现方法分析
2016/06/12 Javascript
JavaScript中数据类型转换总结
2016/12/25 Javascript
jQuery使用ajax_动力节点Java学院整理
2017/07/05 jQuery
Vue2.0 slot分发内容与props验证的方法
2017/12/12 Javascript
详解vue组件开发脚手架
2018/06/15 Javascript
vue-router+nginx 非根路径配置方法
2018/06/30 Javascript
layui加载表格,绑定新增,编辑删除,查看按钮事件的例子
2019/09/06 Javascript
如何在JS文件中获取Vue组件
2020/09/16 Javascript
Vue3不支持Filters过滤器的问题
2020/09/24 Javascript
vue中使用腾讯云Im的示例
2020/10/23 Javascript
Python安装pycurl失败的解决方法
2018/10/15 Python
Django网络框架之HelloDjango项目创建教程
2019/06/06 Python
python opencv 图像拼接的实现方法
2019/06/27 Python
python实现图片中文字分割效果
2019/07/22 Python
Python计算指定日期是今年的第几天(三种方法)
2020/03/26 Python
DRF使用simple JWT身份验证的实现
2021/01/14 Python
农行实习自我鉴定
2013/09/22 职场文书
涉外经济法专业毕业生推荐信
2013/11/24 职场文书
企业消防安全制度
2014/02/02 职场文书
乔布斯斯坦福大学演讲稿
2014/05/23 职场文书
没有孩子的离婚协议书怎么写
2014/09/17 职场文书
2014党委书记四风对照检查材料思想汇报
2014/09/21 职场文书
离婚协议书范本(通用篇)
2014/11/30 职场文书
写给老师的感谢信
2015/01/20 职场文书
小学科学教学计划
2015/01/21 职场文书