AngualrJS中每次$http请求时的一个遮罩层Directive
AngularJS是一款非常强大的前端MVC框架。在AngualrJS中使用$http每次向远程API发送请求,等待响应,这中间有些许的等待过程。如何优雅地处理这个等待过程呢?
如果我们在等待过程中弹出一个遮罩层,会是一个比较优雅的做法。
这就涉及到了对$http的请求响应进行拦截了。请求的时候,弹出一个遮罩层,收到响应的时候把遮罩层隐藏。
其实,$httpProvider已经为我们提供了一个$httpProvider.interceptors属性,我们只需要把自定义的拦截器放到该集合中就可以了。
如何表现呢?大致是这样的:
<divdata-my-overlay> <br/><imgsrc="spinner.gif"/> Loading </div>
显示加载的图片被包含在Directive中了,肯定会用到transclusion。
还涉及到一个遮罩层弹出延迟时间的问题,这个我们希望在config中通过API设置,所以,我们有必要创建一个provider,通过这个设置延迟时间。
$http请求响应遮罩层的Directive:
(function(){
varmyOverlayDirective=function($q,$timeout,$window,httpInterceptor,myOverlayConfig){
return{
restrict:'EA',
transclude:true,
scope:{
myOverlayDelay:"@"
},
template:'<divid="overlay-container"class="onverlayContainer">'+
'<divid="overlay-background"class="onverlayBackground"></div>'+
'<divid="onverlay-content"class="onverlayContent"data-ng-transclude>'+
'</div>'+
'</div>',
link:function(scope,element,attrs){
varoverlayContainer=null,
timePromise=null,
timerPromiseHide=null,
inSession=false,
queue=[],
overlayConfig=myOverlayConfig.getConfig();
init();
//初始化
functioninit(){
wireUpHttpInterceptor();
if(window.jQuery)wirejQueryInterceptor();
overlayContainer=document.getElementById('overlay-container');
}
//自定义Angular的http拦截器
functionwireUpHttpInterceptor(){
//请求拦截
httpInterceptor.request=function(config){
//判断是否满足显示遮罩的条件
if(shouldShowOverlay(config.method,config.url)){
processRequest();
}
returnconfig||$q.when(config);
};
//响应拦截
httpInterceptor.response=function(response){
processResponse();
returnresponse||$q.when(response);
}
//异常拦截
httpInterceptor.responseError=function(rejection){
processResponse();
return$q.reject(rejection);
}
}
//自定义jQuery的http拦截器
functionwirejQueryInterceptor(){
$(document).ajaxStart(function(){
processRequest();
});
$(document).ajaxComplete(function(){
processResponse();
});
$(document).ajaxError(function(){
processResponse();
});
}
//处理请求
functionprocessRequest(){
queue.push({});
if(queue.length==1){
timePromise=$timeout(function(){
if(queue.length)showOverlay();
},scope.myOverlayDelay?scope.myOverlayDelay:overlayConfig.delay);
}
}
//处理响应
functionprocessResponse(){
queue.pop();
if(queue.length==0){
timerPromiseHide=$timeout(function(){
hideOverlay();
if(timerPromiseHide)$timeout.cancel(timerPromiseHide);
},scope.myOverlayDelay?scope.myOverlayDelay:overlayConfig.delay);
}
}
//显示遮罩层
functionshowOverlay(){
varw=0;
varh=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;
}
varcontent=docuemnt.getElementById('overlay-content');
varcontetWidth=parseInt(getComputedStyle(content,'width').replace('px',''));
varcontentHeight=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';
}
functionhideOverlay(){
if(timePromise)$timeout.cancel(timerPromise);
overlayContainer.style.display='none';
}
//得到一个函数的执行结果
vargetComputedStyle=function(){
varfunc=null;
if(document.defaultView&&document.defaultView.getComputedStyle){
func=document.defaultView.getComputedStyle;
}elseif(typeof(document.body.currentStyle)!=="undefined"){
func=function(element,anything){
returnelement["currentStyle"];
}
}
returnfunction(element,style){
reutrnfunc(element,null)[style];
}
}();
//决定是否显示遮罩层
functionshouldShowOverlay(method,url){
varsearchCriteria={
method:method,
url:url
};
returnangular.isUndefined(findUrl(overlayConfig.exceptUrls,searchCriteria));
}
functionfindUrl(urlList,searchCriteria){
varretVal=undefined;
angular.forEach(urlList,function(url){
if(angular.equals(url,searchCriteria)){
retVal=true;
returnfalse;//推出循环
}
})
returnretVal;
}
}
}
};
//配置$httpProvider
varhttpProvider=function($httpProvider){
$httpProvider.interceptors.push('httpInterceptor');
};
//自定义interceptor
varhttpInterceptor=function(){
return{};
};
//提供配置
varmyOverlayConfig=function(){
//默认配置
varconfig={
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
}
functiongetDelayTime(){
returnconfig.delay;
}
functiongetExeptUrls(){
returnconfig.exceptUrls;
}
functiongetConfig(){
returnconfig;
}
};
};
varmyDirectiveApp=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,希望对大家有所帮助。