首页 > 编程 > JavaScript > 正文

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

2019-11-20 10:41:17
字体:
来源:转载
供稿:网友

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;}}}};//配置$httpProvidervar httpProvider = function($httpProvider){$httpProvider.interceptors.push('httpInterceptor');};//自定义interceptorvar httpInterceptor = function(){return {};};//提供配置var myOverlayConfig = function(){//默认配置var config = {delay: 500,exceptUrl: []};//设置延迟this.setDelay = function(delayTime){config.delay = delayTime;}//设置异常处理urlthis.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 ,希望对大家有所帮助。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表