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