簡體   English   中英

AngularJS:僅在一段時間后才顯示對ajax請求加載微調器

[英]AngularJS: Show loading spinner on ajax request only after some time has elapsed

在我的Angular應用程序中,我實現了此指令 (下面的代碼), 該指令基本上使我能夠在Angular檢測到ajax請求時顯示選擇的元素。

但是,為了提高可用性,我想僅在自請求開始起經過一段時間(例如100或200毫秒)后才顯示微調器,以避免在每個單個請求上出現不必要的瞬間顯示。

實現這種事情的最佳方法是什么? 我很難讓setTimeoutif塊中很好地播放,因為即使我不再有待處理的請求,該元素也不會再被隱藏。

.directive('loading',   ['$http' ,function ($http)
{
    return {
        restrict: 'A',
        link: function (scope, elm, attrs)
        {
            scope.isLoading = function () {
                return $http.pendingRequests.length > 0;
            };

            scope.$watch(scope.isLoading, function (v)
            {
                if(v){
                    elm.show();
                } else {
                    elm.hide();
                }
            });
        }
    };
}]);

對於單個全局可用的加載指示器,http攔截器可能是一個更好的策略。 但是假設您要將此元素分別附加到各個元素,請嘗試如下操作:

.directive('loading', ['$http', '$timeout', function($http, $timeout) {
    return {
        restrict: 'A',
        link: function(scope, elm, attrs) {
            scope.isLoading = function() {
                return $http.pendingRequests.length > 0;
            };

            if (scope.isLoading) {
                elm.hide(); // hide the loading indicator to begin with
                // wait 300ms before setting the watcher:
                $timeout(function() {
                    var watcher = scope.$watch(scope.isLoading, function(v) {
                        if (v) {
                            elm.show();
                        } else {
                            elm.hide();
                            watcher(); // don't forget to clear $watches when you don't need them anymore!
                        }
                    });
                }, 300);
            } else {
                // No pending requests on link; hide the element and stop
                elm.hide();

            }
        }
    };
}]);

(您可能還應該在指令上包括$destroy塊,以調用watcher() ,以防該指令超出范圍,而HTTP請求仍處於掛起狀態。)

聽起來您可以利用攔截器並綁定到根變量(而不是指令)來顯示未決ajax請求的元素(在達到時間閾值之后)。 觀察以下可能性...

app.factory('HttpInterceptor', ['$rootScope', '$q', '$timeout', function ($rootScope, $q, $timeout) {

    return {
        'request': function (config) {

            $timeout(function() {
                $rootScope.isLoading = true;    // loading after 200ms
            }, 200);

            return config || $q.when(config);   
        },
        'requestError': function (rejection) {
            /*...*/
            return $q.reject(rejection);
        },
        'response': function (response) {       

            $rootScope.isLoading = false;       // done loading

            return response || $q.when(response);
        },
        'responseError': function (rejection) {
            /*...*/
            return $q.reject(rejection);
        }
    };
}]);

// register interceptor
app.config(['$httpProvider', function ($httpProvider) {
    $httpProvider.interceptors.push('HttpInterceptor');
    /*...*/
}]);

<!-- plain element with binding -->
<div class="whatever" ng-show="isLoading"></div>

JSFiddle Link-工作演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM