Ajax isteği üzerine Angularjs yükleme ekranı


117

Angularjs kullanarak, ajax isteği tamamlanana kadar bir yükleme ekranı (basit bir döndürücü) göstermem gerekiyor. Lütfen bir kod parçacığı ile herhangi bir fikir önerin.




En iyi uygulama, $httpProvider.interceptorsajax isteğinin ne zaman başlayıp ne zaman bittiğini idare edebildiği için kullanmaktır. Bu nedenle $watch, ajax çağrısının ne zaman başladığını ve bittiğini algılamaya artık gerek yoktur.
Frank Myat Per

fabrikamdaki angular-httpshooter'ımı kontrol etmeye ne dersiniz , bu size yükleyiciler ve donma kullanıcı arayüzü için daha iyi kontrol sağlar
Siddharth

Yanıtlar:


210

Veri yükleme durumunu belirtmek için bir kapsam değişkeni ayarlamak yerine, bir direktifin sizin için her şeyi yapması daha iyidir:

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

    }]);

Bu yönerge ile yapmanız gereken tek şey, herhangi bir yükleme animasyonu öğesine bir 'yükleme' özelliği vermektir:

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

Sayfada birden fazla yükleme çarkı olabilir. Bu iplikçilerin nerede ve nasıl yerleştirileceği size bağlıdır ve direktif sizin için onu otomatik olarak açıp kapatacaktır.


burada "loading" yönergesi $ location.path () ile iki kez çağrılıyor. Önce geçerli sayfayla ve sonra hedef sayfayla. Nedeni ne olmalı?
Sanjay D

Mükemmel. Ayrıca, saat üzerinde jquery geçişini de kullanabilirsiniz: elm.toggle (v). Bir $ zaman aşımı oturum monitörüm var ve benim için döndürücüyü yalnızca yarım saniye sonra göstermem gerekiyor. Döndürücüyü daha yavaş göstermek için geçişli bir css uygulayacağım.
Joao Polo

7
Eğer "elm.show () bir işlev değil" hatası alırsanız, açısal yüklemeden önce jquery eklemeniz gerekir.
morpheus05

Scope yapma şeklin benim için çalışmıyor. Bunu jzm'nin yaptığı gibi yapmak zorundaydım (adın etrafında '' kullanarak ve kapsam önekini çıkararak). Herhangi bir fikriniz neden?
KingOfHypocrites

3
Ya eşzamansız yapmam gerekirse. birden fazla farklı alan mı yüklüyorsunuz?
Vadim Ferderer

56

İşte bir örnek. Bool ile basit ng-show yöntemini kullanır.

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

Elbette, yükleme kutusu html kodunu bir yönergeye taşıyabilir ve ardından $ Scope.loading'de $ watch'u kullanabilirsiniz. Bu durumda:

HTML :

<loading></loading>

ANGULARJS DİREKTİFİ :

  .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


Kapsam izleme şekliniz benim için işe yararken, kabul edilen cevap yaklaşımı işe yaramaz.
KingOfHypocrites

@jzm Böyle harika bir çözüm 😊 maalesef çalışmıyor bu çözüm ui-router, neden bilmiyorum
Mo

Bunu bir loading=true
projemde

21

Bunun için ngProgress kullanıyorum .

Script / css dosyalarını HTML'nize ekledikten sonra bağımlılıklarınıza 'ngProgress' ekleyin. Bunu yaptığınızda, bunun gibi bir şey kurabilirsiniz, bu bir rota değişikliği algılandığında tetiklenecektir.

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

AJAX istekleri için aşağıdaki gibi bir şey yapabilirsiniz:

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

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

Bunu yapmadan önce denetleyici bağımlılıklarına 'ngProgress' eklemeyi unutmayın. Birden fazla AJAX isteği yapıyorsanız, AJAX isteklerinizin 'ngProgress.complete ();' çağrılmasından önce ne zaman bittiğini takip etmek için ana uygulama kapsamında artımlı bir değişken kullanın.


15

pendingRequest'leri kullanmak doğru değildir çünkü Açısal belgelerde belirtildiği gibi, bu özellik öncelikle hata ayıklama amacıyla kullanılmak içindir.

Tavsiye ettiğim şey, herhangi bir aktif Async çağrısı olup olmadığını bilmek için bir engelleyici kullanmaktır.

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

ve sonra bir $ watch aracılığıyla activeCalls'ın sıfır olup olmadığını kontrol edin.

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

Bunu yapmanın en iyi yolu , özel yönerge ile birlikte yanıt engelleyicileri kullanmaktır . İşlem, $ rootScope. $ Broadcast & $ rootScope. $ On kullanılarak pub / sub mekanizması kullanılarak daha da iyileştirilebilir . yöntemleri .

Tüm süreç iyi yazılmış bir blog makalesinde belgelendiğinden , bunu burada bir daha tekrar etmeyeceğim. İhtiyaç duyduğunuz uygulamayı bulmak için lütfen bu makaleye bakın.


4

Bu cevaba referans olarak

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

Benim için en iyi çözüm ama jQuery kullanmaktan kaçınmanın bir yolu var.

.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 (); ve (element) .show (); $ kapsam.loadingStatus = 'true' ile; ve $ kapsam.loadingStatus = 'false';

Daha sonra, elemanın ng-show özelliğini ayarlamak için bu değişkeni kullanmanız gerekir.


4

TypeScript ve Açısal Uygulama

direktif

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

Dürbün

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

şablon

<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 kullanıyorsanız (ki bu harika), api çağrıları sırasında bir animasyon oluşturabilirsiniz. İşte benim çözümüm. Bir yanıt yakalayıcı ve bir kök kapsam yayını gönderen bir istek önleyicisi ekleyin. Ardından, bu yanıtı ve isteği dinlemek için bir yönerge oluşturun:

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

Yönerge şu şekildedir:

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

Herhangi bir API yanıtı animasyonu öldürecektir. İstek - yanıt hakkında ek bilgi depolamalı ve yalnızca istekle başlatılan yanıt için tepki vermelisiniz.
Krzysztof Safjanowski

3

Bunu "app.config" inize ekleyin:

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

Ve şu kodu ekleyin:

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

Açısal meşgul kullan :

Uygulamanıza / modülünüze göre cgBusy ekleyin:

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

Sözünüzü ekleyin 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 şablonunuzda:

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

2

Ayrıca, nasıl kullanabileceğinizi gösteren güzel bir demo var Angularjs projenizde animasyonu .

Bağlantı burada (Sol üst köşeye bakın) .

Açık kaynak. İşte indirmek için bağlantı

Ve işte eğitim için bağlantı ;

Demek istediğim, devam edin ve kaynak dosyaları indirin ve ardından döndürücüyü nasıl uyguladıklarını görün. Biraz daha iyi bir yaklaşım kullanmış olabilirler. Öyleyse, bu projeye bir göz atın.


1

Burada basit bir önleme örneği, ajax başladığında fareyi beklemeye ve ajax bittiğinde otomatik olarak ayarladım.

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

Kod, uygulama yapılandırmasına eklenmelidir app.config . Yükleme durumunda fareyi nasıl değiştireceğimi gösterdim, ancak orada herhangi bir yükleyici içeriğini göstermek / gizlemek veya yükleyiciyi gösteren bazı css sınıflarını eklemek, kaldırmak mümkündür.

Interceptor her ajax çağrısında çalışır, bu nedenle her http çağrısında özel boole değişkenleri ($ kapsam.loading = true / false vb.) Oluşturmaya gerek yoktur.

Interceptor, açısal jqLite https://docs.angularjs.org/api/ng/function/angular.element kullanılarak oluşturulmuş olduğundan Jquery gerekmez.


1

Gösteri ve beden nitelikleriyle bir Direktif oluşturun (daha fazlasını da ekleyebilirsiniz)

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

ve html'de şu şekilde kullanın

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

Gelen gösteri değişkeni geçmesine gerçek herhangi söz çalışırken ve bu hale false isteği tamamlandığında. Aktif demo - JsFiddle'da Angular Loader yönergesi örnek demosu


0

@ DavidLin'in cevabını biraz basitleştirmek için geliştirdim - yönergedeki jQuery'ye olan herhangi bir bağımlılığı kaldırdım . Bir üretim uygulamasında kullandığım için bunun çalıştığını onaylayabilirim

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-showGizlemek / göstermek için jQuery çağrısı yerine a kullanıyorum <div>.

İşte <div>açılış <body>etiketinin hemen altına yerleştirdiğim şey :

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

Ve işte bir $ http çağrısı yapılırken kullanıcı arayüzünü engellemek için kaplama sağlayan 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 kredisi @Steve Seeger'e gidiyor - gönderisi: https://stackoverflow.com/a/35470281/335545


0

Bir koşul ekleyebilir ve ardından bunu kök kapsam ile değiştirebilirsiniz. Ajax isteğinizden önce, $ rootScope'u çağırmanız yeterlidir. $ 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();
                        }
                    });
                }
            };

        }]);

Bu kesinlikle en iyi çözüm değil ama yine de işe yarayacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.