Angularjs Ladebildschirm auf Ajax-Anfrage

117

Bei Verwendung von Angularjs muss ein Ladebildschirm (ein einfacher Drehfeld) angezeigt werden, bis die Ajax-Anforderung abgeschlossen ist. Bitte schlagen Sie eine Idee mit einem Code-Snippet vor.

Badhrinath Canessane
quelle
4
Werfen Sie
Ajay Beniwal
Die beste Vorgehensweise ist die Verwendung, $httpProvider.interceptorsda sie verarbeiten kann, wann eine Ajax-Anforderung beginnt und wann sie endet. Aus diesem Grund muss $watchnicht mehr erkannt werden, wann ein Ajax-Anruf beginnt und endet.
Frank Myat Do
Wie wäre es, wenn Sie meinen Factory Angular-httpshooter auschecken , der Ihnen eine bessere Kontrolle über Lader und das Einfrieren der Benutzeroberfläche bietet
Siddharth,

Antworten:

210

Anstatt eine Bereichsvariable einzurichten, um den Status des Datenladens anzuzeigen, ist es besser, wenn eine Direktive alles für Sie erledigt:

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

    }]);

Mit dieser Anweisung müssen Sie lediglich jedem Ladeanimationselement das Attribut "Laden" zuweisen:

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

Sie können mehrere Ladespinner auf der Seite haben. Wo und wie diese Spinner zu gestalten sind, liegt bei Ihnen. Die Richtlinie schaltet sie einfach automatisch für Sie ein / aus.

David Lin
quelle
Hier wird die Direktive "load" zweimal mit $ location.path () aufgerufen. Zuerst mit der aktuellen Seite und dann mit der Zielseite. Was sollte der Grund sein?
Sanjay D
Ausgezeichnet. Außerdem können Sie jquery toggle für watch verwenden: elm.toggle (v). Ich habe einen $ timeout-Sitzungsmonitor und muss den Spinner erst nach einer halben Sekunde anzeigen. Ich werde ein CSS mit Übergang implementieren, um den Spinner langsamer zu zeigen.
Joao Polo
7
Wenn der Fehler "elm.show () ist keine Funktion" angezeigt wird, müssen Sie jquery hinzufügen, bevor Sie eckig laden.
Morpheus05
Die Art und Weise, wie Sie scope.watch ausführen, funktioniert bei mir nicht. Ich musste es so machen, wie es jzm macht (indem ich '' um den Namen herum verwendete und das Bereichspräfix wegließ). Irgendwelche Ideen warum?
KingOfHypocrites
3
Was ist, wenn ich asynchronisieren muss? mehrere verschiedene Bereiche laden?
Vadim Ferderer
56

Hier ist ein Beispiel. Es verwendet die einfache ng-show-Methode mit einem Bool.

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

Natürlich können Sie den HTML-Code der Ladebox in eine Direktive verschieben und dann $ watch für $ scope.loading verwenden. In welchem ​​Fall:

HTML :

<loading></loading>

ANGULARJS RICHTLINIE :

  .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

mnsr
quelle
Die Art und Weise, wie Sie scope.watch ausführen, funktioniert für mich, während der akzeptierte Antwortansatz dies nicht tut.
KingOfHypocrites
@jzm So eine tolle Lösung 😊, leider funktioniert diese Lösung nicht ui-router, weiß nicht warum
Mo.
Ich habe dies in einem meiner Projekte gut funktioniert, in einem anderen Projekt denke ich aufgrund schwerer Ajax-Anfrage loading=truenicht gesetzt zu werden
Alamnaryab
21

Ich benutze dafür ngProgress .

Fügen Sie 'ngProgress' zu Ihren Abhängigkeiten hinzu, sobald Sie die Skript- / CSS-Dateien in Ihren HTML-Code aufgenommen haben. Sobald Sie dies getan haben, können Sie so etwas einrichten, das ausgelöst wird, wenn eine Routenänderung festgestellt wurde.

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

Für AJAX-Anfragen können Sie Folgendes tun:

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

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

Denken Sie daran, den Controller-Abhängigkeiten zuvor 'ngProgress' hinzuzufügen. Wenn Sie mehrere AJAX-Anforderungen ausführen, verwenden Sie eine inkrementelle Variable im Hauptbereich der App, um zu verfolgen, wann Ihre AJAX-Anforderungen abgeschlossen sind, bevor Sie 'ngProgress.complete ();' aufrufen.

Nej Kutcharian
quelle
15

Die Verwendung von pendingRequests ist nicht korrekt, da diese Eigenschaft, wie in der Angular-Dokumentation erwähnt, hauptsächlich für Debugging-Zwecke verwendet werden soll.

Ich empfehle, einen Interceptor zu verwenden, um festzustellen, ob ein Async-Aufruf aktiv ist.

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

und überprüfen Sie dann mit einer $ watch, ob activeCalls in der Direktive Null ist oder nicht.

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();
                }
            });
        }
    };
});
Mahdi K.
quelle
7

Der beste Weg, dies zu tun, besteht darin, Antwort-Interceptors zusammen mit einer benutzerdefinierten Direktive zu verwenden . Der Prozess kann mithilfe des Pub / Sub- Mechanismus mithilfe der Methoden $ rootScope. $ Broadcast & $ rootScope. $ On weiter verbessert werden .

Da der gesamte Prozess in einem gut geschriebenen Blog-Artikel dokumentiert ist , werde ich das hier nicht noch einmal wiederholen. In diesem Artikel finden Sie Informationen zu Ihrer erforderlichen Implementierung.

MN Islam Shihan
quelle
4

In Bezug auf diese Antwort

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

Für mich ist dies die beste Lösung, aber es gibt eine Möglichkeit, die Verwendung von jQuery zu vermeiden.

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

Sie müssen $ (Element) ersetzen .show (); und (Element) .show (); mit $ scope.loadingStatus = 'true'; und $ scope.loadingStatus = 'false';

Dann müssen Sie diese Variable verwenden, um das ng-show-Attribut des Elements festzulegen.

Karsus
quelle
4

Typoskript und Winkelimplementierung

Richtlinie

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

Umfang

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

Vorlage

<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;
}
Code-EZ
quelle
3

Wenn Sie Restangular verwenden (was fantastisch ist), können Sie während API-Aufrufen eine Animation erstellen. Hier ist meine Lösung. Fügen Sie einen Antwort-Interceptor und einen Anforderungs-Interceptor hinzu, die eine Rootscope-Sendung senden. Erstellen Sie dann eine Anweisung, um auf diese Antwort und Anforderung zu warten:

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

Hier ist die Richtlinie:

        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;
        });
      }
    };
  })
;
Enkode
quelle
Jede API-Antwort beendet die Animation. Sie sollten zusätzliche Informationen zu Anfrage - Antwort speichern und nur auf die Antwort reagieren, die durch Anfrage initialisiert wurde.
Krzysztof Safjanowski
3

Fügen Sie dies in Ihre "app.config" ein:

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

Und fügen Sie diesen Code hinzu:

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);
    }
  };
});
BratisLatas
quelle
2

Verwenden Sie eckig beschäftigt :

Fügen Sie cgBusy zu Ihrer App / Ihrem Modul hinzu:

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

Fügen Sie Ihr Versprechen hinzu zu scope:

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

In Ihrer HTML-Vorlage:

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

Außerdem gibt es eine schöne Demo, die zeigt, wie Sie AngularjsAnimationen in Ihrem Projekt verwenden können.

Der Link ist hier (siehe oben links) .

Es ist eine Open Source. Hier ist der Link zum Download

Und hier ist der Link zum Tutorial ;

Mein Punkt ist, gehen Sie voran und laden Sie die Quelldateien herunter und sehen Sie dann, wie sie den Spinner implementiert haben. Sie hätten vielleicht einen etwas besseren Ansatz gewählt. Schauen Sie sich dieses Projekt an.

Idrees Khan
quelle
1

In diesem einfachen Interceptor-Beispiel setze ich die Maus auf Warten, wenn Ajax startet, und auf Auto, wenn Ajax endet.

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

Code muss in der Anwendungskonfiguration hinzugefügt werden app.config. Ich habe gezeigt, wie man die Maus beim Laden ändert, aber dort ist es möglich, Loader-Inhalte ein- / auszublenden oder einige CSS-Klassen hinzuzufügen oder zu entfernen, die den Loader anzeigen.

Interceptor wird bei jedem Ajax-Aufruf ausgeführt, sodass bei jedem http-Aufruf keine speziellen booleschen Variablen ($ scope.loading = true / false usw.) erstellt werden müssen.

Interceptor verwendet integriertes eckiges jqLite https://docs.angularjs.org/api/ng/function/angular.element, sodass keine JQuery erforderlich ist.

Maciej Sikora
quelle
1

Erstellen Sie eine Direktive mit den Attributen show und size (Sie können auch weitere hinzufügen).

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

und in HTML als verwenden

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

Übergeben Sie in der show- Variable true, wenn ein Versprechen ausgeführt wird, und machen Sie dies false, wenn die Anforderung abgeschlossen ist. Aktive Demo - Beispieldemo für eine Angular Loader-Direktive in JsFiddle

Partha Roy
quelle
0

Ich habe ein wenig auf der Antwort von @ DavidLin aufgebaut, um sie zu vereinfachen - und die Abhängigkeit von jQuery in der Direktive zu beseitigen . Ich kann bestätigen, dass dies funktioniert, wenn ich es in einer Produktionsanwendung verwende

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

Ich benutze einen ng-showstatt eines jQuery-Aufrufs, um das auszublenden / anzuzeigen <div>.

Hier ist das, <div>was ich direkt unter dem Eröffnungs- <body>Tag platziert habe:

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

Und hier ist das CSS, das das Overlay zum Blockieren der Benutzeroberfläche bereitstellt, während ein $ http-Aufruf ausgeführt wird:

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

Das CSS-Guthaben geht an @Steve Seeger - seinen Beitrag: https://stackoverflow.com/a/35470281/335545

Bern
quelle
0

Sie können eine Bedingung hinzufügen und sie dann über das Rootscope ändern. Vor Ihrer Ajax-Anfrage rufen Sie einfach $ rootScope auf. $ 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();
                        }
                    });
                }
            };

        }]);

Dies ist definitiv nicht die beste Lösung, aber es würde immer noch funktionieren.

User_3535
quelle