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高级程序设计 错误处理与调试学习笔记
Sep 10 Javascript
jquery多行滚动/向左或向上滚动/响应鼠标实现思路及代码
Jan 23 Javascript
javascript中2个感叹号的用法实例详解
Sep 04 Javascript
js实现按一下删除键删除整个单词附demo
Sep 05 Javascript
js的flv视频播放器插件使用方法
Jun 23 Javascript
DropDownList实现可输入可选择(两种版本可选)
Dec 07 Javascript
JS实现页面进入和返回定位到具体位置
Dec 08 Javascript
Vue 2.X的状态管理vuex记录详解
Mar 23 Javascript
React中的render何时执行过程
Apr 13 Javascript
jQuery中$原理实例分析
Aug 13 jQuery
解决微信浏览器缓存站点入口文件(IIS部署Vue项目)
Jun 17 Javascript
浅谈Vue组件单元测试究竟测试什么
Feb 05 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
ThinkPHP模板输出display用法分析
2014/11/26 PHP
php常用表单验证类用法实例
2015/06/18 PHP
php实现推荐功能的简单实例
2019/09/29 PHP
javascript学习随笔(使用window和frame)的技巧
2007/03/08 Javascript
javascript call和apply方法
2008/11/24 Javascript
jQuery 选择器、DOM操作、事件、动画
2010/11/25 Javascript
JavaScript动态插入script的基本思路及实现函数
2013/11/11 Javascript
Js实现动态添加删除Table行示例
2014/04/14 Javascript
JS 调试中常见的报错问题解决方法
2017/05/20 Javascript
实现图片首尾平滑轮播(JS原生方法—节流)
2017/10/17 Javascript
Vue中的基础过渡动画及实现原理解析
2018/12/04 Javascript
JavaScript深入V8引擎以及编写优化代码的5个技巧
2019/06/24 Javascript
flexible.js实现移动端rem适配方案
2020/04/07 Javascript
python的几种开发工具介绍
2007/03/07 Python
python实现下载指定网址所有图片的方法
2015/08/08 Python
Python内置函数OCT详解
2016/11/09 Python
Python heapq使用详解及实例代码
2017/01/25 Python
Python爬虫实现网页信息抓取功能示例【URL与正则模块】
2017/05/18 Python
django之session与分页(实例讲解)
2017/11/13 Python
http请求 request失败自动重新尝试代码示例
2018/01/25 Python
python opencv之分水岭算法示例
2018/02/24 Python
不知道这5种下划线的含义,你就不算真的会Python!
2018/10/09 Python
python使用插值法画出平滑曲线
2018/12/15 Python
Python对Tornado请求与响应的数据处理
2020/02/12 Python
python能在浏览器能运行吗
2020/06/17 Python
django rest framework使用django-filter用法
2020/07/15 Python
Laravel的加密解密与哈希实例讲解
2021/03/24 PHP
初三物理教学反思
2014/01/21 职场文书
小学生个人先进事迹材料
2014/05/08 职场文书
派出所正风肃纪剖析材料
2014/10/10 职场文书
2019年自助餐厅创业计划书模板
2019/08/22 职场文书
Oracle设置DB、监听和EM开机启动的方法
2021/04/25 Oracle
python实现简单聊天功能
2021/07/07 Python
Python中可变和不可变对象的深入讲解
2021/08/02 Python
分享五个Node.js开发的优秀实践 
2022/04/07 NodeJs
MyBatis在注解上使用动态SQL方式(@select使用if)
2022/07/07 Java/Android