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

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

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


当前回答

如果我们知道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调用。

其他回答

只需使用ng-show和一个布尔值

不需要使用指令,不需要变得复杂。

下面是代码,可以放在提交按钮旁边,或者放在你想要旋转器的任何位置:

<span ng-show="dataIsLoading">
  <img src="http://www.nasa.gov/multimedia/videogallery/ajax-loader.gif" style="height:20px;"/>
</span>

然后在控制器中:

$scope.dataIsLoading = true

let url = '/whatever_Your_URL_Is'
$http.get(url)
.then(function(response) {
  $scope.dataIsLoading = false
})
Based on Josh David Miller response:

  <body>
  <header>
  </header>
<div class="spinner" ng-show="loading">
  <div class="loader" ></div>
</div>

<div ng-view=""></div>

<footer>
</footer>

</body>

添加这个css:

    .loader {
  border: 16px solid #f3f3f3;
  border-radius: 50%;
  border-top: 16px solid #3498db;
  border-bottom : 16px solid black;
  width: 80px;
  height: 80px;
  -webkit-animation: spin 2s linear infinite;
  animation: spin 2s linear infinite;
  position: absolute;
  top: 45%;
  left: 45%;
}

@-webkit-keyframes spin {
  0% { -webkit-transform: rotate(0deg); }
  100% { -webkit-transform: rotate(360deg); }
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}


.spinner{
  width: 100%;
height: 100%;
z-index: 10000;
position: absolute;
top: 0;
left: 0;
margin: 0 auto;
text-align: center;
vertical-align: middle;
background: white;
opacity: 0.6;
}

在你的角补充:

rootScope美元。加载= false; rootScope美元。加载= true;- $http时为>。会结束。

这是添加旋转器最简单的方法,我猜:-

您可以将ng-show与这些漂亮的旋转器中的任何一个的div标签一起使用 http://tobiasahlin.com/spinkit/{{这不是我的页面}}

然后你可以用这种逻辑

/ / ajax开始 美元scope.finderloader = true; http({美元 方法:“文章”, url: "你的url ", Data:{//你的数据 } })。然后(函数mysucceeded (response) { 美元scope.finderloader = false; 美元scope.search = false; 美元的范围。myData = response.data.records; }); / / ajax结束 <div ng-show="finderloader" class=spinner></div> //在HTML的正确位置添加这个

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

对于资源,如下所示:

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

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

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

如果你在一个服务/工厂中包装你的api调用,那么你可以跟踪那里的加载计数器(每个答案和@JMaylin的优秀同步建议),并通过一个指令引用加载计数器。或其任何组合。

API 包装器

yourModule
    .factory('yourApi', ['$http', function ($http) {
        var api = {}

        //#region ------------ spinner -------------

        // ajax loading counter
        api._loading = 0;

        /**
         * Toggle check
         */
        api.isOn = function () { return api._loading > 0; }

        /**
         * Based on a configuration setting to ignore the loading spinner, update the loading counter
         * (for multiple ajax calls at one time)
         */
        api.spinner = function(delta, config) {
            // if we haven't been told to ignore the spinner, change the loading counter
            // so we can show/hide the spinner

            if (NG.isUndefined(config.spin) || config.spin) api._loading += delta;

            // don't let runaway triggers break stuff...
            if (api._loading < 0) api._loading = 0;

            console.log('spinner:', api._loading, delta);
        }
        /**
         * Track an ajax load begin, if not specifically disallowed by request configuration
         */
        api.loadBegin = function(config) {
            api.spinner(1, config);
        }
        /**
         * Track an ajax load end, if not specifically disallowed by request configuration
         */
        api.loadEnd = function (config) {
            api.spinner(-1, config);
        }

        //#endregion ------------ spinner -------------

        var baseConfig = {
            method: 'post'
            // don't need to declare `spin` here
        }

        /**
         * $http wrapper to standardize all api calls
         * @param args stuff sent to request
         * @param config $http configuration, such as url, methods, etc
         */
        var callWrapper = function(args, config) {
            var p = angular.extend(baseConfig, config); // override defaults

            // fix for 'get' vs 'post' param attachment
            if (!angular.isUndefined(args)) p[p.method == 'get' ? 'params' : 'data'] = args;

            // trigger the spinner
            api.loadBegin(p);

            // make the call, and turn of the spinner on completion
            // note: may want to use `then`/`catch` instead since `finally` has delayed completion if down-chain returns more promises
            return $http(p)['finally'](function(response) {
                api.loadEnd(response.config);
                return response;
            });
        }

        api.DoSomething = function(args) {
            // yes spinner
            return callWrapper(args, { cache: true });
        }
        api.DoSomethingInBackground = function(args) {
            // no spinner
            return callWrapper(args, { cache: true, spin: false });
        }

        // expose
        return api;
    });

微调控制项指令

(function (NG) {
    var loaderTemplate = '<div class="ui active dimmer" data-ng-show="hasSpinner()"><div class="ui large loader"></div></div>';

    /**
     * Show/Hide spinner with ajax
     */
    function spinnerDirective($compile, api) {
        return {
            restrict: 'EA',
            link: function (scope, element) {
                // listen for api trigger
                scope.hasSpinner = api.isOn;

                // attach spinner html
                var spin = NG.element(loaderTemplate);
                $compile(spin)(scope); // bind+parse
                element.append(spin);
            }
        }
    }

    NG.module('yourModule')
        .directive('yourApiSpinner', ['$compile', 'yourApi', spinnerDirective]);
})(angular);

使用

<div ng-controller="myCtrl" your-api-spinner> ... </div>