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

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

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


当前回答

这是我的解决方案,我觉得比其他贴在这里的要容易得多。虽然不知道它有多“漂亮”,但它解决了我所有的问题

我有一个css样式叫做loading

.loading { display: none; }

加载div的html可以是任何东西,但我使用了一些FontAwesome图标和旋转方法:

<div style="text-align:center" ng-class="{ 'loading': !loading }">
    <br />
    <h1><i class="fa fa-refresh fa-spin"></i> Loading data</h1>
</div>

在你想要隐藏的元素上,你只需这样写:

<something ng-class="{ 'loading': loading }" class="loading"></something>

在函数中,我把这个设为load。

(function (angular) {
    function MainController($scope) {
        $scope.loading = true

我使用的是SignalR,所以在hubProxy.client.allLocks函数(当它完成了通过锁),我只是把

 $scope.loading = false
 $scope.$apply();

当页面加载时,这也隐藏了{{someField}},因为我在load上设置了加载类,AngularJS随后删除了它。

其他回答

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

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

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

像这样称呼它:

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

这是GitHub。

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

bower install angular-busy --save

这是我的解决方案,我觉得比其他贴在这里的要容易得多。虽然不知道它有多“漂亮”,但它解决了我所有的问题

我有一个css样式叫做loading

.loading { display: none; }

加载div的html可以是任何东西,但我使用了一些FontAwesome图标和旋转方法:

<div style="text-align:center" ng-class="{ 'loading': !loading }">
    <br />
    <h1><i class="fa fa-refresh fa-spin"></i> Loading data</h1>
</div>

在你想要隐藏的元素上,你只需这样写:

<something ng-class="{ 'loading': loading }" class="loading"></something>

在函数中,我把这个设为load。

(function (angular) {
    function MainController($scope) {
        $scope.loading = true

我使用的是SignalR,所以在hubProxy.client.allLocks函数(当它完成了通过锁),我只是把

 $scope.loading = false
 $scope.$apply();

当页面加载时,这也隐藏了{{someField}},因为我在load上设置了加载类,AngularJS随后删除了它。

由于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
});

})

希望这对你有所帮助。

如果我们知道DRY的概念,那么所有的答案都是复杂的,或者需要在每个请求上设置一些变量,这是非常错误的做法。这里是一个简单的拦截器的例子,当ajax启动时,我将鼠标设置为等待,当ajax结束时设置为自动。

$httpProvider.interceptors.push(function($document) {
    return {
     'request': function(config) {
         // here ajax start
         // here we can for example add some class or show somethin
         $document.find("body").css("cursor","wait");

         return config;
      },

      'response': function(response) {
         // here ajax ends
         //here we should remove classes added on request start

         $document.find("body").css("cursor","auto");

         return response;
      }
    };
  });

代码必须添加到应用程序配置app.config中。我展示了如何改变鼠标加载状态,但在那里,它是可以显示/隐藏任何加载器内容,或添加,删除一些css类显示加载器。

拦截器将在每次ajax调用上运行,因此不需要创建特殊的布尔变量($scope. js)。加载=true/false等)在每个HTTP调用。

这对我来说很管用:

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将评估它是“真实的”。一旦承诺被解决,这将自动更新…这正是我们想要的。