[angularjs] AngularJS에서 $ http 요청 중에 spinner GIF를 표시 하시겠습니까?

내가 사용하고 $httpAjax 요청을 만들기 위해 AngularJS와의 서비스.

Ajax 요청이 실행되는 동안 스피너 GIF (또는 다른 유형의 통화 중 표시기)를 어떻게 표시 할 수 있습니까?

ajaxstarteventAngularJS 문서에서 와 같은 것을 보지 못했습니다 .



답변

현재 과거 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(); 

토글합니다. 참고 : 위는 포스트 시작시 각도 모듈에서 사용됩니다

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


답변

이것은 실제로 특정 사용 사례에 따라 다르지만 간단한 방법은 다음과 같은 패턴을 따릅니다.

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


답변

여기에 사용 된 버전입니다 directiveng-hide.

앵귤러 서비스 를 통한 모든 호출 중에 로더가 표시됩니다 $http.

템플릿에서 :

<div class="loader" data-loading></div>

지령:

angular.module('app')
  .directive('loading', ['$http', function ($http) {
    return {
      restrict: 'A',
      link: function (scope, element, attrs) {
        scope.isLoading = function () {
          return $http.pendingRequests.length > 0;
        };
        scope.$watch(scope.isLoading, function (value) {
          if (value) {
            element.removeClass('ng-hide');
          } else {
            element.addClass('ng-hide');
          }
        });
      }
    };
}]);

ng-hide요소 에서 클래스를 사용하면 jquery를 피할 수 있습니다.


맞춤 설정 : interceptor

로딩 인터셉터를 작성하면 조건에 따라 로더를 표시하거나 숨길 수 있습니다.

지령:

var loadingDirective = function ($rootScope) {
  return function ($scope, element, attrs) {
      $scope.$on("loader_show", function () {
          return element.removeClass('ng-hide');
      });
      return $scope.$on("loader_hide", function () {
          return element.addClass('ng-hide');
      });
  };
};

인터셉터 :

  • 예를 들면 : 표시되지 않는 spinner경우response.background === true;
  • 가로 채기 request및 / 또는 response설정 $rootScope.$broadcast("loader_show");또는$rootScope.$broadcast("loader_hide");

인터셉터 작성에 대한 추가 정보


답변

ngResource를 사용하는 경우 객체의 $ resolved 속성이 로더에 유용합니다.

다음과 같은 자원의 경우 :

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

로더를 자원 오브젝트의 $ resolved 속성에 링크 할 수 있습니다.

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


답변

https://github.com/wongatech/angular-http-loader 는이를위한 좋은 프로젝트입니다.

예를 들어 http://wongatech.github.io/angular-http-loader/

아래 코드는 요청이 발생할 때 템플릿 example / loader.tpl.html을 보여줍니다.

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


답변

angular-busy비동기 호출에 따라 작은 로더를 표시하는 지시문을 발견했습니다 .

예를 들어을 (를) 만들어야하는 GET경우 $scope,

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

다음과 같이 호출하십시오.

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

여기 GitHub있습니다.

다음을 사용하여 설치할 수도 bower있습니다 (프로젝트 종속성을 업데이트하는 것을 잊지 마십시오).

bower install angular-busy --save


답변

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>