AngularJS 是一款非常强大的前端 MVC 框架。接下来通过本文给大家介绍 AngualrJS 中每次 $http 请求时的一个遮罩层 Directive,本文非常具有参考借鉴价值,特此分享供大家学习
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
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: ''
- });
- }]);
- }());
来源: http://www.phperz.com/article/17/0215/267369.html