Ajax 요청에 대한 Angularjs 로딩 화면


117

Angularjs를 사용하여 ajax 요청이 완료 될 때까지 로딩 화면 (간단한 스피너)을 표시해야합니다. 코드 조각으로 아이디어를 제안하십시오.




모범 사례는 $httpProvider.interceptorsajax 요청이 시작될 때와 끝날 때를 처리 할 수 ​​있기 때문에 사용 하는 것입니다. 그렇기 때문에 $watch더 이상 ajax 호출이 시작되고 종료되는시기를 감지 할 필요가 없습니다.
Frank Myat Thu

당신이 내 공장 체크 아웃에 대해 어떻게 각-httpshooter을 , 그것은 당신에게 로더에 대한 더 나은 제어 및 동결 UI를 제공
싯다 르트 나라 얀

답변:


210

데이터로드 상태를 나타 내기 위해 범위 변수를 설정하는 대신 지시문이 모든 작업을 수행하도록하는 것이 좋습니다.

angular.module('directive.loading', [])

    .directive('loading',   ['$http' ,function ($http)
    {
        return {
            restrict: 'A',
            link: function (scope, elm, attrs)
            {
                scope.isLoading = function () {
                    return $http.pendingRequests.length > 0;
                };

                scope.$watch(scope.isLoading, function (v)
                {
                    if(v){
                        elm.show();
                    }else{
                        elm.hide();
                    }
                });
            }
        };

    }]);

이 지시문을 사용하면 로딩 애니메이션 요소에 'loading'속성을 부여하기 만하면됩니다.

<div class="loading-spiner-holder" data-loading ><div class="loading-spiner"><img src="..." /></div></div>

페이지에로드 스피너가 여러 개있을 수 있습니다. 스피너를 배치하는 위치와 방법은 귀하에게 달려 있으며 지시문은 자동으로 켜고 끌 것입니다.


여기서 "loading"지시문은 $ location.path ()와 함께 두 번 호출됩니다. 첫 번째는 현재 페이지이고 다음은 대상 페이지입니다. 그 이유는 무엇입니까?
Sanjay D

우수한. 또한 watch : elm.toggle (v)에서 jquery toggle을 사용할 수 있습니다. $ timeout 세션 모니터가 있는데 0.5 초 후에 만 ​​스피너를 표시해야합니다. 회 전자를 더 느리게 표시하기 위해 전환이있는 CSS를 구현합니다.
Joao Polo

7
"elm.show () is not a function"오류가 발생하면 angular를로드하기 전에 jquery를 추가해야합니다.
morpheus05

당신이 scope.watch를하는 방식은 저에게 효과가 없습니다. 나는 jzm이하는 방식으로해야했다 (이름 주위에 ''를 사용하고 범위 접두사를 생략함으로써). 이유는 무엇입니까?
KingOfHypocrites

3
비동기가 필요한 경우 어떻게해야합니까? 여러 영역을로드 하시겠습니까?
Vadim Ferderer

56

여기에 예가 있습니다. bool과 함께 간단한 ng-show 방법을 사용합니다.

HTML

<div ng-show="loading" class="loading"><img src="...">LOADING...</div>
<div ng-repeat="car in cars">
  <li>{{car.name}}</li>
</div>
<button ng-click="clickMe()" class="btn btn-primary">CLICK ME</button>

ANGULARJS

  $scope.clickMe = function() {
    $scope.loading = true;
    $http.get('test.json')
      .success(function(data) {
        $scope.cars = data[0].cars;
        $scope.loading = false;
    });
  }

물론 로딩 박스 html 코드를 지시어로 옮긴 다음 $ scope.loading에서 $ watch를 사용할 수 있습니다. 이 경우 :

HTML :

<loading></loading>

ANGULARJS 지시 :

  .directive('loading', function () {
      return {
        restrict: 'E',
        replace:true,
        template: '<div class="loading"><img src="..."/>LOADING...</div>',
        link: function (scope, element, attr) {
              scope.$watch('loading', function (val) {
                  if (val)
                      $(element).show();
                  else
                      $(element).hide();
              });
        }
      }
  })

PLUNK : http://plnkr.co/edit/AI1z21?p=preview


Scope.watch를 수행하는 방식은 수락 된 답변 접근 방식이 그렇지 않은 경우 나를 위해 작동합니다.
KingOfHypocrites

@jzm 그런 훌륭한 솔루션 😊, 불행히도이 솔루션은 작동 ui-router하지 않습니다. 이유를 모르겠습니다
Mo.

나는 때문에 무거운 아약스 요청에 내가 생각하는 다른 프로젝트에 벌금을 일한 내 프로젝트 중 하나에 이런 짓을 loading=true하지 설정 얻을
alamnaryab

21

이를 위해 ngProgress 를 사용 합니다.

HTML에 스크립트 / css 파일을 포함시킨 후 종속성에 'ngProgress'를 추가하십시오. 이렇게하면 경로 변경이 감지 될 때 트리거되는 이와 같은 것을 설정할 수 있습니다.

angular.module('app').run(function($rootScope, ngProgress) {
  $rootScope.$on('$routeChangeStart', function(ev,data) {
    ngProgress.start();
  });
  $rootScope.$on('$routeChangeSuccess', function(ev,data) {
    ngProgress.complete();
  });
});

AJAX 요청의 경우 다음과 같이 할 수 있습니다.

$scope.getLatest = function () {
    ngProgress.start();

    $http.get('/latest-goodies')
         .success(function(data,status) {
             $scope.latest = data;
             ngProgress.complete();
         })
         .error(function(data,status) {
             ngProgress.complete();
         });
};

그렇게하기 전에 컨트롤러 종속성에 'ngProgress'를 추가하는 것을 잊지 마십시오. 여러 AJAX 요청을 수행하는 경우 기본 앱 범위에서 증분 변수를 사용하여 'ngProgress.complete ();'를 호출하기 전에 AJAX 요청이 언제 완료되었는지 추적합니다.


15

Angular 문서에서 언급했듯이이 속성은 주로 디버깅 목적으로 사용되기 때문에 pendingRequests를 사용하는 것은 올바르지 않습니다.

내가 권장하는 것은 인터셉터를 사용하여 활성 비동기 호출이 있는지 확인하는 것입니다.

module.config(['$httpProvider', function ($httpProvider) {
    $httpProvider.interceptors.push(function ($q, $rootScope) {
        if ($rootScope.activeCalls == undefined) {
            $rootScope.activeCalls = 0;
        }

        return {
            request: function (config) {
                $rootScope.activeCalls += 1;
                return config;
            },
            requestError: function (rejection) {
                $rootScope.activeCalls -= 1;
                return rejection;
            },
            response: function (response) {
                $rootScope.activeCalls -= 1;
                return response;
            },
            responseError: function (rejection) {
                $rootScope.activeCalls -= 1;
                return rejection;
            }
        };
    });
}]);

그런 다음 $ watch를 통해 지시문에서 activeCalls가 0인지 여부를 확인하십시오.

module.directive('loadingSpinner', function ($http) {
    return {
        restrict: 'A',
        replace: true,
        template: '<div class="loader unixloader" data-initialize="loader" data-delay="500"></div>',
        link: function (scope, element, attrs) {

            scope.$watch('activeCalls', function (newVal, oldVal) {
                if (newVal == 0) {
                    $(element).hide();
                }
                else {
                    $(element).show();
                }
            });
        }
    };
});

7

이를 수행하는 가장 좋은 방법은 사용자 지정 지시문 과 함께 응답 인터셉터 를 사용하는 것 입니다. 그리고 pub / sub 메커니즘을 사용 하여 프로세스를 더욱 향상시킬 수 있습니다. $ rootScope. $ broadcast & $ rootScope. $ on 메소드를 .

전체 프로세스가 잘 작성된 블로그 기사에 문서화되어 있으므로 여기서 다시 반복하지 않겠습니다. 필요한 구현에 대해서는 해당 기사를 참조하십시오.


4

이 답변을 참조하여

https://stackoverflow.com/a/17144634/4146239

나에게는 최상의 솔루션이지만 jQuery 사용을 피하는 방법이 있습니다.

.directive('loading', function () {
      return {
        restrict: 'E',
        replace:true,
        template: '<div class="loading"><img src="http://www.nasa.gov/multimedia/videogallery/ajax-loader.gif" width="20" height="20" />LOADING...</div>',
        link: function (scope, element, attr) {
              scope.$watch('loading', function (val) {
                  if (val)
                      scope.loadingStatus = 'true';
                  else
                      scope.loadingStatus = 'false';
              });
        }
      }
  })

  .controller('myController', function($scope, $http) {
      $scope.cars = [];
      
      $scope.clickMe = function() {
        scope.loadingStatus = 'true'
        $http.get('test.json')
          .success(function(data) {
            $scope.cars = data[0].cars;
            $scope.loadingStatus = 'false';
        });
      }
      
  });
<body ng-app="myApp" ng-controller="myController" ng-init="loadingStatus='true'">
        <loading ng-show="loadingStatus" ></loading>
  
        <div ng-repeat="car in cars">
          <li>{{car.name}}</li>
        </div>
        <button ng-click="clickMe()" class="btn btn-primary">CLICK ME</button>
  
</body>

$ (element) .show (); 대체해야합니다. 및 (요소) .show (); $ scope.loadingStatus = 'true'로; 그리고 $ scope.loadingStatus = 'false';

보다,이 변수를 사용하여 요소의 ng-show 속성을 설정해야합니다.


4

Typescript 및 Angular 구현

지령

((): void=> {
    "use strict";
    angular.module("app").directive("busyindicator", busyIndicator);
    function busyIndicator($http:ng.IHttpService): ng.IDirective {
        var directive = <ng.IDirective>{
            restrict: "A",
            link(scope: Scope.IBusyIndicatorScope) {
                scope.anyRequestInProgress = () => ($http.pendingRequests.length > 0);
                scope.$watch(scope.anyRequestInProgress, x => {            
                    if (x) {
                        scope.canShow = true;
                    } else {
                        scope.canShow = false;
                    }
                });
            }
        };
        return directive;
    }
})();

범위

   module App.Scope {
        export interface IBusyIndicatorScope extends angular.IScope {
            anyRequestInProgress: any;
            canShow: boolean;
        }
    }  

주형

<div id="activityspinner" ng-show="canShow" class="show" data-busyindicator>
</div>

CSS
#activityspinner
{
    display : none;
}
#activityspinner.show {
    display : block;
    position : fixed;
    z-index: 100;
    background-image : url('data:image/gif;base64,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') 
    -ms-opacity : 0.4;
    opacity : 0.4;
    background-repeat : no-repeat;
    background-position : center;
    left : 0;
    bottom : 0;
    right : 0;
    top : 0;
}

3

Restangular를 사용하고 있다면 (굉장합니다) API 호출 중에 애니메이션을 만들 수 있습니다. 여기 내 해결책이 있습니다. 응답 인터셉터와 루트 스코프 브로드 캐스트를 보내는 요청 인터셉터를 추가합니다. 그런 다음 해당 응답 및 요청을 수신하는 지시문을 만듭니다. :

         angular.module('mean.system')
  .factory('myRestangular',['Restangular','$rootScope', function(Restangular,$rootScope) {
    return Restangular.withConfig(function(RestangularConfigurer) {
      RestangularConfigurer.setBaseUrl('http://localhost:3000/api');
      RestangularConfigurer.addResponseInterceptor(function(data, operation, what, url, response, deferred) {
        var extractedData;
        // .. to look for getList operations
        if (operation === 'getList') {
          // .. and handle the data and meta data
          extractedData = data.data;
          extractedData.meta = data.meta;
        } else {
          extractedData = data.data;
        }
        $rootScope.$broadcast('apiResponse');
        return extractedData;
      });
      RestangularConfigurer.setRequestInterceptor(function (elem, operation) {
        if (operation === 'remove') {
          return null;
        }
        return (elem && angular.isObject(elem.data)) ? elem : {data: elem};
      });
      RestangularConfigurer.setRestangularFields({
        id: '_id'
      });
      RestangularConfigurer.addRequestInterceptor(function(element, operation, what, url) {
        $rootScope.$broadcast('apiRequest');
        return element;
      });
    });
  }]);

다음은 지시문입니다.

        angular.module('mean.system')
  .directive('smartLoadingIndicator', function($rootScope) {
    return {
      restrict: 'AE',
      template: '<div ng-show="isAPICalling"><p><i class="fa fa-gear fa-4x fa-spin"></i>&nbsp;Loading</p></div>',
      replace: true,
      link: function(scope, elem, attrs) {
        scope.isAPICalling = false;

        $rootScope.$on('apiRequest', function() {
          scope.isAPICalling = true;
        });
        $rootScope.$on('apiResponse', function() {
          scope.isAPICalling = false;
        });
      }
    };
  })
;

모든 API 응답은 애니메이션을 종료합니다. 요청-응답에 대한 추가 정보를 저장하고 요청에 의해 초기화 된 응답에 대해서만 반응해야합니다.
Krzysztof Safjanowski 2015

3

"app.config"에 다음을 포함하십시오.

 $httpProvider.interceptors.push('myHttpInterceptor');

그리고 다음 코드를 추가합니다.

app.factory('myHttpInterceptor', function ($q, $window,$rootScope) {
    $rootScope.ActiveAjaxConectionsWithouthNotifications = 0;
    var checker = function(parameters,status){
            //YOU CAN USE parameters.url TO IGNORE SOME URL
            if(status == "request"){
                $rootScope.ActiveAjaxConectionsWithouthNotifications+=1;
                $('#loading_view').show();
            }
            if(status == "response"){
                $rootScope.ActiveAjaxConectionsWithouthNotifications-=1;

            }
            if($rootScope.ActiveAjaxConectionsWithouthNotifications<=0){
                $rootScope.ActiveAjaxConectionsWithouthNotifications=0;
                $('#loading_view').hide();

            }


    };
return {
    'request': function(config) {
        checker(config,"request");
        return config;
    },
   'requestError': function(rejection) {
       checker(rejection.config,"request");
      return $q.reject(rejection);
    },
    'response': function(response) {
         checker(response.config,"response");
      return response;
    },
   'responseError': function(rejection) {
        checker(rejection.config,"response");
      return $q.reject(rejection);
    }
  };
});

2

사용 각도 바쁜 :

앱 / 모듈에 cgBusy를 추가합니다.

angular.module('your_app', ['cgBusy']);

다음에 대한 약속 추가 scope:

function MyCtrl($http, User) {
  //using $http
  this.isBusy = $http.get('...');
  //if you have a User class based on $resource
  this.isBusy = User.$save();
}

HTML 템플릿에서 :

<div cg-busy="$ctrl.isBusy"></div>

2

또한 Angularjs프로젝트에서 애니메이션 을 사용하는 방법을 보여주는 멋진 데모가 있습니다 .

링크는 여기에 있습니다 (왼쪽 상단 참조) .

오픈 소스입니다. 다운로드 링크는 다음과 같습니다.

그리고 여기 튜토리얼 링크가 있습니다 .

내 요점은 계속해서 소스 파일을 다운로드 한 다음 스피너를 어떻게 구현했는지 확인하는 것입니다. 그들은 조금 더 나은 앞치마를 사용했을 것입니다. 따라서이 프로젝트를 확인하십시오.


1

여기 간단한 인터셉터 예제에서는 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 호출에서 실행되므로 모든 http 호출에서 특수 부울 변수 ($ scope.loading = true / false 등)를 만들 필요가 없습니다.

인터셉터는 angular jqLite https://docs.angularjs.org/api/ng/function/angular.element 에서 빌드를 사용 하므로 Jquery가 필요하지 않습니다.


1

show 및 size 속성을 사용하여 지시문을 만듭니다 (더 추가 할 수도 있음).

    app.directive('loader',function(){
    return {
    restrict:'EA',
    scope:{
        show : '@',
      size : '@'
    },
    template : '<div class="loader-container"><div class="loader" ng-if="show" ng-class="size"></div></div>'
  }
})

그리고 html에서 다음과 같이 사용하십시오.

 <loader show="{{loader1}}" size="sm"></loader>

에서 변수 통과 사실 어떤 약속이 실행 중일 때 그하게 거짓을 요청이 완료 될 때. 활성 데모 -JsFiddle의 Angular Loader 지시문 예제 데모


0

나는 지시문 에서 jQuery 에 대한 종속성을 제거 하기 위해 @DavidLin의 답변을 약간 작성했습니다 . 프로덕션 응용 프로그램에서 사용하므로 이것이 작동하는지 확인할 수 있습니다.

function AjaxLoadingOverlay($http) {

    return {
        restrict: 'A',
        link: function ($scope, $element, $attributes) {

            $scope.loadingOverlay = false;

            $scope.isLoading = function () {
                return $http.pendingRequests.length > 0;
            };

            $scope.$watch($scope.isLoading, function (isLoading) {
                $scope.loadingOverlay = isLoading;
            });
        }
    };
}   

ng-showjQuery 호출 대신을 사용 하여 <div>.

여기의 <div>난 그냥 오프닝 아래에 배치하는 <body>태그 :

<div ajax-loading-overlay class="loading-overlay" ng-show="loadingOverlay">
    <img src="Resources/Images/LoadingAnimation.gif" />
</div>

그리고 다음은 $ http 호출이 수행되는 동안 UI를 차단하는 오버레이를 제공하는 CSS입니다.

.loading-overlay {
    position: fixed;
    z-index: 999;
    height: 2em;
    width: 2em;
    overflow: show;
    margin: auto;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
}

.loading-overlay:before {
    content: '';
    display: block;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0,0,0,0.3);
}

/* :not(:required) hides these rules from IE9 and below */
.loading-overlay:not(:required) {
    font: 0/0 a;
    color: transparent;
    text-shadow: none;
    background-color: transparent;
    border: 0;
}

CSS 크레딧은 @Steve Seeger 's-그의 게시물 : https://stackoverflow.com/a/35470281/335545로 이동합니다.


0

조건을 추가 한 다음 루트 스코프를 통해 변경할 수 있습니다. ajax 요청 전에 $ rootScope. $ emit ( 'stopLoader');

angular.module('directive.loading', [])
        .directive('loading',   ['$http', '$rootScope',function ($http, $rootScope)
        {
            return {
                restrict: 'A',
                link: function (scope, elm, attrs)
                {
                    scope.isNoLoadingForced = false;
                    scope.isLoading = function () {
                        return $http.pendingRequests.length > 0 && scope.isNoLoadingForced;
                    };

                    $rootScope.$on('stopLoader', function(){
                        scope.isNoLoadingForced = true;
                    })

                    scope.$watch(scope.isLoading, function (v)
                    {
                        if(v){
                            elm.show();
                        }else{
                            elm.hide();
                        }
                    });
                }
            };

        }]);

이것은 확실히 최선의 해결책은 아니지만 여전히 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.