AngualrJS中每次$http請求時的一個遮罩層Directive

来源:http://www.cnblogs.com/darrenji/archive/2016/01/26/5160501.html
-Advertisement-
Play Games

在AngualrJS中使用$http每次向遠程API發送請求,等待響應,這中間有些許的等待過程。如何優雅地處理這個等待過程呢?如果我們在等待過程中彈出一個遮罩層,會是一個比較優雅的做法。這就涉及到了對$http的請求響應進行攔截了。請求的時候,彈出一個遮罩層,收到響應的時候把遮罩層隱藏。其實,$ht...


 

在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: ''
                });
        }]);
}());

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • .mb{16 background-color:#9e9e9e;filter:Alpha(Opacity=60);position:absolute;opacity:0.6;top:0;left:0;z-index:10;18 }
  • 1滑鼠移上去在圖片上層添加一個蒙版 下邊附上代碼和實現效果案例 2 3 4 5 6 7 8 9 10 26 33 34 35 36 ...
  • HTML5目前最新的規範(標準)是2014年10月推出 2005年左右出現HTML5版本(非標準) W3C組織(兩個組織定義H5規範) 學習(研究)HTML5是學習未來(將來主流) HTML版本 - 第一階段主要學習還是4版本(包含5版本) HTML5版本之後,聲明不再出現版本信息 ...
  • js 節點 document html css 表單節點操作節點操作:訪問、屬性、創建(1)節點的訪問:firstChild、lastChild、childNodes、parentChild(父子節) 可以使用元素對象的方法進行代替:getElementById()、getElemen...
  • 在後臺管理系統開發的過程中,上左右的佈局是最常見的頁面佈局方式,現在我們來看看使用easyui這個jquery前端框架如何快速搭建一個可用的頁面框架。1.在頁面中引入easyui所需的文件1 2 3 4 5 6 7 2.在頁面body部分構建必要的html結構 ...
  • 通常我們這樣寫一個菜單: Orders 菜單項是否高亮顯示取決於controller中的highlight方法。vm.highlight = funciton(path){ return $locaiton.path().substr(0, path.lenght)...
  • js 隨機星星 document.createElement(); setAttribute()無標題文檔
  • 一、Jquery List DragSort 對於有些頁面,如首頁的定製,需要進行動態的拖拽排序。由於自己實現比較困難,我們一般會使用一些js插件來實現。dragsort 就是幫助我們完成這一需求。通過dragsort我們可以很方便地對html頁面上的素動態地推拽,進行排序。dragsort是一.....
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...