Angularjs memuat layar pada permintaan ajax

117

Dengan menggunakan Angularjs, saya perlu menampilkan layar pemuatan (spinner sederhana) hingga permintaan ajax selesai. Harap sarankan ide apa pun dengan cuplikan kode.

Badhrinath Canessane
sumber
Praktik terbaik digunakan $httpProvider.interceptorskarena dapat menangani kapan permintaan ajax dimulai dan kapan itu berakhir. Itulah mengapa $watchtidak perlu lagi mendeteksi kapan ajax call dimulai dan diakhiri.
Frank Myat Kam
bagaimana kalau Anda memeriksa angular-httpshooter pabrik saya , ini memberi Anda kontrol yang lebih baik untuk pemuat dan pembekuan UI
Siddharth

Jawaban:

210

Daripada menyiapkan variabel cakupan untuk menunjukkan status pemuatan data, lebih baik memiliki direktif yang melakukan segalanya untuk Anda:

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

    }]);

Dengan arahan ini, yang perlu Anda lakukan adalah memberikan elemen animasi pemuatan dengan atribut 'loading':

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

Anda dapat memiliki beberapa pemintal pemuatan di halaman. di mana dan bagaimana mengatur tata letak pemintal itu terserah Anda dan direktif hanya akan mengaktifkan / menonaktifkannya untuk Anda secara otomatis.

David Lin
sumber
di sini direktif "loading" dipanggil dua kali, dengan $ location.path (). Pertama dengan halaman saat ini dan selanjutnya dengan halaman tujuan. Apa alasannya?
Sanjay D
Luar biasa. Dan juga, Anda dapat menggunakan jquery toggle di jam tangan: elm.toggle (v). Saya memiliki pemantau sesi batas waktu $, dan bagi saya, saya perlu menunjukkan pemintal hanya setelah setengah detik. Saya akan mengimplementasikan css dengan transisi untuk menampilkan spinner dengan lebih lambat.
Joao Polo
7
Jika Anda mendapatkan kesalahan "elm.show () bukan fungsi", Anda harus menambahkan jquery sebelum memuat angular.
morpheus05
Cara Anda melakukan scope.watch tidak berhasil untuk saya. Saya harus melakukannya dengan cara jzm melakukannya (dengan menggunakan '' di sekitar nama dan menghilangkan awalan cakupan). Ada ide mengapa?
KingOfHypocrites
3
Bagaimana jika saya perlu melakukan async. memuat beberapa area berbeda?
Vadim Ferderer
56

Berikut contohnya. Ia menggunakan metode ng-show sederhana dengan 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;
    });
  }

Tentu saja Anda dapat memindahkan kode html kotak pemuatan ke dalam sebuah direktif, lalu gunakan $ watch di $ scope.loading. Dalam hal ini:

HTML :

<loading></loading>

ANGULARJS DIRECTIVE :

  .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
sumber
Cara Anda melakukan scope.watch bekerja untuk saya sedangkan pendekatan jawaban yang diterima tidak.
KingOfHypocrites
@jzm Solusi yang sangat bagus 😊, sayangnya solusi ini tidak berfungsi ui-router, tidak tahu mengapa
Mo.
Saya melakukan ini di salah satu proyek saya bekerja dengan baik, di proyek lain saya pikir karena permintaan ajax yang berat loading=truetidak dapat diatur
alamnaryab
21

Saya menggunakan ngProgress untuk ini.

Tambahkan 'ngProgress' ke dependensi Anda setelah Anda menyertakan file script / css di HTML Anda. Setelah Anda melakukannya, Anda dapat mengatur sesuatu seperti ini, yang akan dipicu ketika perubahan rute terdeteksi.

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

Untuk permintaan AJAX, Anda dapat melakukan sesuatu seperti ini:

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

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

Ingatlah untuk menambahkan 'ngProgress' ke dependensi pengontrol sebelum melakukannya. Dan jika Anda melakukan beberapa permintaan AJAX, gunakan variabel inkremental dalam cakupan aplikasi utama untuk melacak saat permintaan AJAX Anda selesai sebelum memanggil 'ngProgress.complete ();'.

Nej Kutcharian
sumber
15

menggunakan pendingRequests tidak benar karena seperti yang disebutkan dalam dokumentasi Angular, properti ini terutama dimaksudkan untuk digunakan untuk tujuan debugging.

Yang saya rekomendasikan adalah menggunakan pencegat untuk mengetahui apakah ada panggilan Async aktif.

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

dan kemudian periksa apakah activeCalls nol atau tidak di direktif melalui $ watch.

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

Cara terbaik untuk melakukannya adalah dengan menggunakan pencegat respons bersama dengan perintah khusus . Dan proses selanjutnya dapat ditingkatkan menggunakan mekanisme pub / sub menggunakan metode $ rootScope. $ Broadcast & $ rootScope. $ On .

Karena seluruh proses didokumentasikan dalam artikel blog yang ditulis dengan baik , saya tidak akan mengulanginya lagi di sini. Silakan merujuk ke artikel itu untuk mendapatkan implementasi yang Anda butuhkan.

MN Islam Shihan
sumber
4

Mengacu pada jawaban ini

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

Bagi saya adalah solusi terbaik tetapi ada cara untuk menghindari penggunaan 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>

Anda perlu mengganti $ (element) .show (); dan (elemen) .show (); dengan $ scope.loadingStatus = 'true'; dan $ scope.loadingStatus = 'false';

Kemudian, Anda perlu menggunakan variabel ini untuk menyetel atribut ng-show dari elemen tersebut.

Karsus
sumber
4

Ketikan dan Implementasi Angular

pengarahan

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

Cakupan

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

Template

<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;
}
Kode-EZ
sumber
3

Jika Anda menggunakan Restangular (yang luar biasa), Anda dapat membuat animasi selama panggilan api. Inilah solusi saya. Tambahkan interceptor respons dan interseptor permintaan yang mengirimkan siaran rootscope. Kemudian buat arahan untuk mendengarkan respons dan permintaan itu .:

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

Berikut arahannya:

        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
sumber
Respons API apa pun akan mematikan animasi. Anda harus menyimpan informasi tambahan tentang request - response, dan bereaksi hanya untuk respon tersebut yang diinisialisasi oleh request.
Krzysztof Safjanowski
3

Sertakan ini di "app.config" Anda:

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

Dan tambahkan kode ini:

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
sumber
2

Gunakan angular-busy :

Tambahkan cgBusy ke aplikasi / modul Anda:

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

Tambahkan janji Anda untuk scope:

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

Di template html Anda:

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

Juga, ada demo bagus yang menunjukkan bagaimana Anda bisa menggunakan Angularjsanimasi dalam proyek Anda.

Tautannya ada di sini (Lihat pojok kiri atas) .

Ini open source. Ini tautan untuk mengunduh

Dan ini tautan untuk tutorial ;

Maksud saya adalah, lanjutkan dan unduh file sumber dan kemudian lihat bagaimana mereka mengimplementasikan spinner. Mereka mungkin menggunakan pendekatan yang sedikit lebih baik. Jadi, selesaikan proyek ini.

Idrees Khan
sumber
1

Berikut contoh interseptor sederhana, saya mengatur mouse untuk menunggu ketika ajax dimulai dan mengaturnya ke otomatis ketika ajax berakhir.

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

Kode harus ditambahkan dalam konfigurasi aplikasi app.config. Saya menunjukkan cara mengubah mouse saat memuat status tetapi di sana dimungkinkan untuk menampilkan / menyembunyikan konten loader apa pun, atau menambahkan, menghapus beberapa kelas css yang menampilkan loader.

Interceptor akan berjalan pada setiap panggilan ajax, jadi tidak perlu membuat variabel boolean khusus ($ scope.loading = true / false dll.) Pada setiap panggilan http.

Interceptor menggunakan jqLite bersudut yang dibangun di https://docs.angularjs.org/api/ng/function/angular.element sehingga tidak diperlukan Jquery.

Maciej Sikora
sumber
1

Buat Directive dengan atribut show and size (Anda juga bisa menambahkan lebih banyak)

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

dan dalam html digunakan sebagai

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

Dalam variabel show, berikan true saat ada promise yang dijalankan dan buat false saat permintaan selesai. Demo aktif - Demo contoh direktif Angular Loader di JsFiddle

Partha Roy
sumber
0

Saya membangun jawaban @ DavidLin sedikit untuk menyederhanakannya - menghilangkan ketergantungan pada jQuery dalam arahan. Saya dapat mengonfirmasi bahwa ini berfungsi saat saya menggunakannya dalam aplikasi produksi

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

Saya menggunakan ng-showalih - alih panggilan jQuery untuk menyembunyikan / menampilkan file <div>.

Inilah <div>yang saya tempatkan tepat di bawah <body>tag pembuka :

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

Dan inilah CSS yang menyediakan overlay untuk memblokir UI saat panggilan $ http sedang dibuat:

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

Kredit CSS diberikan ke @Steve Seeger - postingannya: https://stackoverflow.com/a/35470281/335545

Bern
sumber
0

Anda dapat menambahkan kondisi dan kemudian mengubahnya melalui rootscope. Sebelum permintaan ajax Anda, Anda cukup memanggil $ 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();
                        }
                    });
                }
            };

        }]);

Ini jelas bukan solusi terbaik tetapi masih akan berhasil.

Pengguna_3535
sumber