欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

AngualrJS中每次$http请求时的一个遮罩层Directive

程序员文章站 2022-06-06 20:31:21
angularjs是一款非常强大的前端mvc框架。在angualrjs中使用$http每次向远程api发送请求,等待响应,这中间有些许的等待过程。如何优雅地处理这个等待过程...

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 ,希望对大家有所帮助。