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

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

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


当前回答

由于position:fixed的功能最近发生了变化,我很难将gif加载器显示在所有元素之上,所以我不得不使用angular内置的jQuery。

Html

<div ng-controller="FetchController">
      <div id="spinner"></div>
</div>

Css

#spinner {display: none}
body.spinnerOn #spinner { /* body tag not necessary actually */
   display: block;
   height: 100%;
   width: 100%;
   background: rgba(207, 13, 48, 0.72) url(img/loader.gif) center center no-repeat;
   position: fixed;
   top: 0;
   left: 0;
   z-index: 9999;
}
body.spinnerOn main.content { position: static;} /* and whatever content needs to be moved below your fixed loader div */

控制器

app.controller('FetchController', ['$scope', '$http', '$templateCache', '$location', '$q',
function($scope, $http, $templateCache, $location, $q) {

angular.element('body').addClass('spinnerOn'); // add Class to body to show spinner

$http.post( // or .get(
    // your data here
})
.then(function (response) {
    console.info('success');     
    angular.element('body').removeClass('spinnerOn'); // hide spinner

    return response.data;               
}, function (response) {                   
    console.info('error'); 
    angular.element('body').removeClass('spinnerOn'); // hide spinner
});

})

希望这对你有所帮助。

其他回答

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

.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>

https://github.com/wongatech/angular-http-loader是一个很好的项目。

例如http://wongatech.github.io/angular-http-loader/

下面的代码显示了发生请求时的模板示例/loader.tpl.html。

<div ng-http-loader template="example/loader.tpl.html"></div>

下面是我的实现,就像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"/>

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

对于页面加载和模态,最简单的方法是使用ng-show指令并使用一个作用域数据变量。喜欢的东西:

ng-show="angular.isUndefined(scope.data.someObject)".

在这里,当someObject未定义时,旋转器将显示。一旦服务返回数据并填充someObject,微调器将返回其隐藏状态。