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 相关文章推荐
浅析Cookie中的Path与domain
Dec 18 Javascript
ES6中如何使用Set和WeakSet
Mar 10 Javascript
深入理解逻辑表达式的用法 与或非的用法
Jun 06 Javascript
强大Vue.js组件浅析
Sep 12 Javascript
javascript经典特效分享 手风琴、轮播图、图片滑动
Sep 14 Javascript
理解javascript中的Function.prototype.bind的方法
Feb 03 Javascript
JavaScript无缝滚动效果的实例代码
Mar 27 Javascript
JavaScript Drum Kit 指南(纯 JS 模拟敲鼓效果)
Jul 23 Javascript
Vue打包后出现一些map文件的解决方法
Feb 13 Javascript
vue-vuex中使用commit提交mutation来修改state的方法详解
Sep 16 Javascript
javascript开发实现贪吃蛇游戏
Jul 31 Javascript
Vue解决移动端弹窗滚动穿透问题
Dec 15 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
用 PHP5 轻松解析 XML
2006/12/04 PHP
PHP实现MySQL更新记录的代码
2008/06/07 PHP
php模板引擎技术简单实现
2016/03/15 PHP
脚本收藏iframe
2006/07/21 Javascript
使用TextRange获取输入框中光标的位置的代码
2007/03/08 Javascript
javascript concat数组累加 示例
2009/09/03 Javascript
JavaScript 基础篇(一)
2012/03/30 Javascript
Jquery Validate 正则表达式实用验证代码大全
2013/08/23 Javascript
JavaScript中检测变量是否存在遇到的一些问题
2013/11/11 Javascript
Iframe实现跨浏览器自适应高度解决方法
2014/09/02 Javascript
jQuery使用getJSON方法获取json数据完整示例
2016/09/13 Javascript
EasyUI 结合JS导出Excel文件的实现方法
2016/11/10 Javascript
基于jQuery实现一个marquee无缝滚动的插件
2017/03/09 Javascript
ES6新特性八:async函数用法实例详解
2017/04/21 Javascript
JS中使用media实现响应式布局
2017/08/04 Javascript
Vue.js watch监视属性知识点总结
2019/11/11 Javascript
JS script脚本中async和defer区别详解
2020/06/24 Javascript
[01:31]DOTA2上海特级锦标赛 SECRET战队完整宣传片
2016/03/16 DOTA
python实现通过shelve修改对象实例
2014/09/26 Python
Python 字典dict使用介绍
2014/11/30 Python
Window环境下Scrapy开发环境搭建
2018/11/18 Python
Python使用正则表达式分割字符串的实现方法
2019/07/16 Python
Python异步编程之协程任务的调度操作实例分析
2020/02/01 Python
keras 简单 lstm实例(基于one-hot编码)
2020/07/02 Python
深入浅析Python代码规范性检测
2020/07/31 Python
基于OpenCV的网络实时视频流传输的实现
2020/11/15 Python
python实现杨辉三角的几种方法代码实例
2021/03/02 Python
CSS3实现超酷的黑猫警长首页
2016/04/26 HTML / CSS
Net Remoting把服务器端激活两种模式
2014/01/22 面试题
金鑫耀Java笔试题
2014/09/06 面试题
公司保密承诺书
2014/03/27 职场文书
国际商务专业求职信
2014/07/15 职场文书
后勤工作个人总结
2015/02/28 职场文书
2015年党建工作目标责任书
2015/05/08 职场文书
看完这篇文章获得一些java if优化技巧
2021/07/15 Java/Android
Nginx 配置 HTTPS的详细过程
2022/05/30 Servers