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

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

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


当前回答

这对我来说很管用:

HTML:

  <div id="loader" class="ng-hide" ng-show="req.$$state.pending">
    <img class="ajax-loader" 
         width="200" 
         height="200" 
         src="/images/spinner.gif" />
  </div>

角:

  $scope.req = $http.get("/admin/view/"+id).success(function(data) {          
      $scope.data = data;
  });

当$http返回的承诺是未决的,ng-show将评估它是“真实的”。一旦承诺被解决,这将自动更新…这正是我们想要的。

其他回答

如果你正在使用ngResource,对象的$resolved属性对加载器很有用:

对于资源,如下所示:

var User = $resource('/user/:id', {id:'@id'});
var user = User.get({id: 1})

你可以将加载器链接到资源对象的$resolved属性:

<div ng-hide="user.$resolved">Loading ...</div>

这真的取决于你的特定用例,但一个简单的方法是遵循这样的模式:

.controller('MainCtrl', function ( $scope, myService ) {
  $scope.loading = true;
  myService.get().then( function ( response ) {
    $scope.items = response.data;
  }, function ( response ) {
    // TODO: handle the error somehow
  }).finally(function() {
    // called no matter success or failure
    $scope.loading = false;
  });
});

然后在模板中对它做出反应:

<div class="spinner" ng-show="loading"></div>
<div ng-repeat="item in items>{{item.name}}</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; } }; })

下面是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>

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

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

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

像这样称呼它:

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

这是GitHub。

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

bower install angular-busy --save