我正在使用AngularJS的$http服务来进行Ajax请求。

如何在Ajax请求执行时显示旋转GIF(或另一种类型的忙碌指示器)?

我在AngularJS文档中没有看到类似ajaxstartevent的东西。


当前回答

下面是我的实现,就像ng-show和请求计数器一样简单。

它使用一个新的服务为所有请求$http:

myApp.service('RqstSrv', [ '$http', '$rootScope', function($http, $rootScope) {
    var rqstService = {};

    rqstService.call = function(conf) {

        $rootScope.currentCalls = !isNaN($rootScope.currentCalls) ?  $rootScope.currentCalls++ : 0;

        $http(conf).then(function APICallSucceed(response) {
            // Handle success
        }, function APICallError(response) {
            // Handle error
        }).then(function() {
            $rootScope.currentCalls--;
        });
    }
} ]);

然后你可以根据当前调用的数量使用你的加载器:

<img data-ng-show="currentCalls > 0" src="images/ajax-loader.gif"/>

其他回答

刚刚发现了angular-busy指令,它显示了一个依赖于某些异步调用的小加载器。

例如,如果你必须创建一个GET,在$作用域中引用承诺,

$scope.req = $http.get('http://google.fr');

像这样称呼它:

<div cg-busy="req"></div>

这是GitHub。

你也可以使用bower安装它(别忘了更新你的项目依赖项):

bower install angular-busy --save

下面是AngularJS当前使用的咒语:

angular.module('SharedServices', [])
    .config(function ($httpProvider) {
        $httpProvider.responseInterceptors.push('myHttpInterceptor');
        var spinnerFunction = function (data, headersGetter) {
            // todo start the spinner here
            //alert('start spinner');
            $('#mydiv').show();
            return data;
        };
        $httpProvider.defaults.transformRequest.push(spinnerFunction);
    })
// register the interceptor as a service, intercepts ALL angular ajax http calls
    .factory('myHttpInterceptor', function ($q, $window) {
        return function (promise) {
            return promise.then(function (response) {
                // do something on success
                // todo hide the spinner
                //alert('stop spinner');
                $('#mydiv').hide();
                return response;

            }, function (response) {
                // do something on error
                // todo hide the spinner
                //alert('stop spinner');
                $('#mydiv').hide();
                return $q.reject(response);
            });
        };
    });

//regular angular initialization continued below....
angular.module('myApp', [ 'myApp.directives', 'SharedServices']).
//.......

这里是它的其余部分(HTML / CSS)....使用

$('#mydiv').show(); 
$('#mydiv').hide(); 

来切换它。注意:以上是在post开头的angular模块中使用的

#mydiv {  
    position:absolute;
    top:0;
    left:0;
    width:100%;
    height:100%;
    z-index:1000;
    background-color:grey;
    opacity: .8;
 }

.ajax-loader {
    position: absolute;
    left: 50%;
    top: 50%;
    margin-left: -32px; /* -1 * image width / 2 */
    margin-top: -32px;  /* -1 * image height / 2 */
    display: block;     
}

<div id="mydiv">
    <img src="lib/jQuery/images/ajax-loader.gif" class="ajax-loader"/>
</div>

下面的方法将记录所有的请求,并且只在所有请求完成时隐藏:

app.factory('httpRequestInterceptor', function(LoadingService, requestCount) { return { request: function(config) { if (!config.headers.disableLoading) { requestCount.increase(); LoadingService.show(); } return config; } }; }).factory('httpResponseInterceptor', function(LoadingService, $timeout, error, $q, requestCount) { function waitAndHide() { $timeout(function() { if (requestCount.get() === 0){ LoadingService.hide(); } else{ waitAndHide(); } }, 300); } return { response: function(config) { requestCount.descrease(); if (requestCount.get() === 0) { waitAndHide(); } return config; }, responseError: function(config) { requestCount.descrease(); if (requestCount.get() === 0) { waitAndHide(); } var deferred = $q.defer(); error.show(config.data, function() { deferred.reject(config); }); return deferred.promise; } }; }).factory('requestCount', function() { var count = 0; return { increase: function() { count++; }, descrease: function() { if (count === 0) return; count--; }, get: function() { return count; } }; })

简单的方法没有拦截器或jQuery

这是一种显示旋转器的简单方法,不需要第三方库、拦截器或jQuery。

在控制器中设置和重置标志位。

function starting() {
    //ADD SPINNER
    vm.starting = true;
    $http.get(url)
      .then(function onSuccess(response) {
        vm.data = response.data;
    }).catch(function onReject(errorResponse) {
        console.log(errorResponse.status);
    }).finally(function() {
        //REMOVE SPINNER
        vm.starting = false;
    });
};

在HTML中,使用标记:

<div ng-show="vm.starting">
    <img ng-src="spinnerURL" />
</div>

<div ng-hide="vm.starting">
    <p>{{vm.data}}</p>
</div>

vm。当XHR开始时设置为true,当XHR完成时清除。

你可以使用angular interceptor来管理http请求调用

  <div class="loader">
    <div id="loader"></div>
  </div>

<script>
    var app = angular.module("myApp", []);

    app.factory('httpRequestInterceptor', ['$rootScope', '$location', function ($rootScope, $location) {
        return {
            request: function ($config) {
                $('.loader').show();
                return $config;
            },
            response: function ($config) {
                $('.loader').hide();
                return $config;
            },
            responseError: function (response) {
                return response;
            }
        };
    }]);

    app.config(['$stateProvider', '$urlRouterProvider', '$httpProvider',
        function ($stateProvider, $urlRouterProvider, $httpProvider) {
            $httpProvider.interceptors.push('httpRequestInterceptor');
        }]);

</script>

https://stackoverflow.com/a/49632155/4976786