Showing Spinner GIF during $http request in Angula

2019-01-01 04:40发布

I am using the $http service of angular to make an ajax request.

How to show a loader gif during the ajax request?

I don't see any ajaxstartevent or similar event in documentation.

标签: angularjs
25条回答
初与友歌
2楼-- · 2019-01-01 05:03

You can use angular interceptor to manage http request calls

  <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

查看更多
心情的温度
3楼-- · 2019-01-01 05:04

Here are the current past AngularJS incantations:

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']).
//.......

Here is the rest of it (HTML / CSS)....using

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

to toggle it. NOTE: the above is used in the angular module at beginning of post

#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>
查看更多
忆尘夕之涩
4楼-- · 2019-01-01 05:04

If you are using ngResource, the $resolved attribute of an object is useful for loaders:

For a resource as follows:

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

You can link a loader to the $resolved attribute of the resource object:

<div ng-hide="user.$resolved">Loading ...</div>
查看更多
无色无味的生活
5楼-- · 2019-01-01 05:05

This really depends on your specific use case, but a simple way would follow a pattern like this:

.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;
  });
});

And then react to it in your template:

<div class="spinner" ng-show="loading"></div>
<div ng-repeat="item in items>{{item.name}}</div>
查看更多
荒废的爱情
6楼-- · 2019-01-01 05:05

For page loads and modals the easiest way is to use the ng-show direcive and use one of the scope data variables. Something like ng-show="angular.isUndefined(scope.data.someobject)". As the data is undefined the spinner will show. Once the service returns with data and scope is populated, the spinner will be hidden.

查看更多
孤独寂梦人
7楼-- · 2019-01-01 05:05

The following way will take note of all requests, and hide only once all requests are done:

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

查看更多
登录 后发表回答