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


    在AngualrJS中使用$http每次向远程API发送请求,等待响应,这中间有些许的等待过程。如何优雅地处理这个等待过程呢?

    如果我们在等待过程中弹出一个遮罩层,会是一个比较优雅的做法。

    这就涉及到了对$http的请求响应进行拦截了。请求的时候,弹出一个遮罩层,收到响应的时候把遮罩层隐藏。

    其实,$httpProvider已经为我们提供了一个$httpProvider.interceptors属性,我们只需要把自定义的拦截器放到该集合中就可以了。

    如何表现呢?大致是这样的:

    <div data-my-overlay>
        <br/><img src="spinner.gif" /> &nbsp;&nbsp;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: ''
                    });
            }]);
    }());
  • 相关阅读:
    创建git项目的feature分支以及下载特定分支的仓库代码
    C++读取文件
    linux解压eclipse启动时无法找到jre环境的解决办法
    ubuntu安装谷歌浏览器
    web项目脱离Eclipse在Tomcat部署并配置Eclipse调试
    阿里巴巴连接池Druid简单使用
    gc overhead limit exceeded
    onload方法注意点
    获取Spring管理的Bean
    Java应用中使用ShutdownHook友好地清理现场
  • 原文地址:https://www.cnblogs.com/darrenji/p/5160501.html
Copyright © 2020-2023  润新知