Màn hình tải Angularjs theo yêu cầu ajax


117

Sử dụng Angularjs, tôi cần hiển thị màn hình tải (một con quay đơn giản) cho đến khi yêu cầu ajax hoàn tất. Vui lòng đề xuất bất kỳ ý tưởng nào với một đoạn mã.




Phương pháp hay nhất là sử dụng $httpProvider.interceptorsvì nó có thể xử lý khi nào yêu cầu ajax bắt đầu và khi nào nó kết thúc. Đó là lý do tại sao $watchkhông còn cần thiết để phát hiện khi nào cuộc gọi ajax bắt đầu và kết thúc.
Frank Myat Thu

như thế nào về bạn kiểm nhà máy của tôi góc-httpshooter , nó cung cấp cho bạn kiểm soát tốt hơn cho xe nâng bốc và đóng băng UI
Siddharth

Câu trả lời:


210

Thay vì thiết lập một biến phạm vi để chỉ ra trạng thái tải dữ liệu, tốt hơn nên có một chỉ thị thực hiện mọi thứ cho bạn:

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

    }]);

Với chỉ thị này, tất cả những gì bạn cần làm là cung cấp cho bất kỳ phần tử hoạt ảnh đang tải nào thuộc tính 'loading':

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

Bạn có thể có nhiều trình quay đang tải trên trang. Vị trí và cách bố trí các spinners đó là tùy thuộc vào bạn và chỉ thị sẽ tự động bật / tắt nó cho bạn.


ở đây chỉ thị "loading" đang được gọi hai lần, với $ location.path (). Đầu tiên với trang hiện tại và tiếp theo với trang đích. Lý do nên là gì?
Sanjay D

Thông minh. Ngoài ra, bạn có thể sử dụng chuyển đổi jquery trên đồng hồ: elm.toggle (v). Tôi có một trình theo dõi phiên thời gian chờ $ và đối với tôi, tôi cần hiển thị vòng quay chỉ sau nửa giây. Tôi sẽ thực hiện một css với quá trình chuyển đổi để hiển thị chậm hơn con quay.
Joao Polo

7
Nếu bạn gặp lỗi "elm.show () không phải là một hàm", bạn phải thêm jquery trước khi tải góc.
morpheus

Cách bạn làm scope.watch không phù hợp với tôi. Tôi đã phải làm theo cách jzm làm (bằng cách sử dụng '' xung quanh tên và bỏ qua tiền tố phạm vi). Bất kỳ ý tưởng tại sao?
KingOfHypocrites vào

3
Điều gì xảy ra nếu tôi cần không đồng bộ hóa. tải nhiều khu vực khác nhau?
Vadim Ferderer

56

Đây là một ví dụ. Nó sử dụng phương pháp ng-show đơn giản với 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;
    });
  }

Tất nhiên, bạn có thể di chuyển mã html của hộp tải thành một chỉ thị, sau đó sử dụng $ watch trên $ scope.loading. Trong trường hợp:

HTML :

<loading></loading>

CHỈ ĐẠO 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


Cách bạn thực hiện scope.watch phù hợp với tôi trong khi cách tiếp cận câu trả lời được chấp nhận thì không.
KingOfHypocrites

@jzm một giải pháp tuyệt vời như vậy 😊, không may giải pháp này không làm việc với ui-router, không biết lý do tại sao
Mo.

Tôi đã làm điều này trong một trong những dự án của tôi đã làm việc tốt, trong một dự án khác tôi nghĩ rằng do yêu cầu ajax nặng loading=truekhông được thiết lập
alamnaryab

21

Tôi sử dụng ngProgress cho việc này.

Thêm 'ngProgress' vào các phần phụ thuộc của bạn khi bạn đã đưa các tệp script / css vào HTML của mình. Sau khi bạn làm điều đó, bạn có thể thiết lập một cái gì đó như thế này, cái này sẽ kích hoạt khi phát hiện thấy thay đổi tuyến đường.

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

Đối với các yêu cầu AJAX, bạn có thể làm như sau:

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

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

Chỉ cần nhớ thêm 'ngProgress' vào các phần phụ thuộc của bộ điều khiển trước khi thực hiện. Và nếu bạn đang thực hiện nhiều yêu cầu AJAX, hãy sử dụng một biến tăng dần trong phạm vi ứng dụng chính để theo dõi thời điểm các yêu cầu AJAX của bạn hoàn tất trước khi gọi 'ngProgress.complete ();'.


15

sử dụng pendingRequests là không đúng vì như đã đề cập trong tài liệu Angular, thuộc tính này chủ yếu được sử dụng cho mục đích gỡ lỗi.

Những gì tôi khuyên bạn nên sử dụng một bộ đánh chặn để biết liệu có bất kỳ cuộc gọi Async đang hoạt động nào không.

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

và sau đó kiểm tra xem ActiveCalls có bằng 0 hay không trong chỉ thị thông qua $ 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();
                }
            });
        }
    };
});

7

Cách tốt nhất để làm điều này là sử dụng đánh chặn phản ứng cùng với chỉ thị tùy chỉnh . Và quá trình này có thể được cải thiện hơn nữa bằng cách sử dụng cơ chế pub / sub sử dụng $ rootScope. $ Broadcast & $ rootScope. $ Trên các phương thức.

Vì toàn bộ quá trình được ghi lại trong một bài báo blog được viết tốt , tôi sẽ không lặp lại điều đó ở đây một lần nữa. Hãy tham khảo bài viết đó để đưa ra cách thực hiện cần thiết của bạn.


4

Tham khảo câu trả lời này

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

Đối với tôi là giải pháp tốt nhất nhưng có một cách để tránh sử dụng 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>

Bạn cần thay thế $ (element) .show (); và (phần tử) .show (); với $ scope.loadingStatus = 'true'; và $ scope.loadingStatus = 'false';

Hơn nữa, bạn cần sử dụng biến này để đặt thuộc tính ng-show của phần tử.


4

Bản ghi và triển khai Angular

chỉ thị

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

Phạm vi

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

Bản mẫu

<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

Nếu bạn đang sử dụng Restangular (thật tuyệt vời), bạn có thể tạo hoạt ảnh trong các cuộc gọi api. Đây là giải pháp của tôi. Thêm một bộ đánh chặn phản hồi và một bộ đánh chặn yêu cầu gửi một chương trình phát sóng rootcope. Sau đó, tạo một chỉ thị để lắng nghe phản hồi và yêu cầu đó:

         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 là chỉ thị:

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

Bất kỳ phản hồi API nào cũng sẽ giết hoạt ảnh. Bạn nên lưu trữ thông tin bổ sung về yêu cầu - phản hồi và chỉ phản ứng cho phản hồi đó đã được khởi tạo theo yêu cầu.
Krzysztof Safjanowski vào

3

Bao gồm điều này trong "app.config" của bạn:

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

Và thêm mã này:

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

Sử dụng góc bận :

Thêm cgBusy vào ứng dụng / mô-đun của bạn:

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

Thêm lời hứa của bạn vào scope:

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

Trong mẫu html của bạn:

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

2

Ngoài ra, có một bản demo đẹp cho thấy cách bạn có thể sử dụng Angularjs hoạt ảnh trong dự án của mình.

Liên kết ở đây (Xem góc trên cùng bên trái) .

Đó là một mã nguồn mở. Đây là liên kết để tải về

Và đây là liên kết để hướng dẫn ;

Quan điểm của tôi là, hãy tiếp tục và tải xuống các tệp nguồn và sau đó xem chúng đã triển khai spinner như thế nào. Họ có thể đã sử dụng aproach tốt hơn một chút. Vì vậy, hãy kiểm tra dự án này.


1

Đây là ví dụ đơn giản về đánh chặn, tôi đặt chuột chờ khi ajax bắt đầu và đặt nó thành tự động khi ajax kết thúc.

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

Mã phải được thêm vào cấu hình ứng dụng app.config . Tôi đã chỉ ra cách thay đổi trạng thái chuột khi tải nhưng trong đó có thể hiển thị / ẩn bất kỳ nội dung trình tải nào hoặc thêm, xóa một số lớp css đang hiển thị trình tải.

Interceptor sẽ chạy trên mọi lệnh gọi ajax, vì vậy không cần tạo các biến boolean đặc biệt ($ scope.loading = true / false, v.v.) trên mọi lệnh gọi http.

Interceptor đang sử dụng được xây dựng trong jqLite https://docs.angularjs.org/api/ng/ Chức năng / angular.element, nên không cần Jquery.


1

Tạo Chỉ thị với các thuộc tính hiển thị và kích thước (bạn cũng có thể thêm các thuộc tính khác)

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

và trong html, sử dụng như

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

Trong biến hiển thị, truyền true khi bất kỳ lời hứa nào đang chạy và biến điều đó thành false khi yêu cầu được hoàn thành. Bản demo hoạt động - Bản demo ví dụ về chỉ thị Angular Loader trong JsFiddle


0

Tôi đã xây dựng câu trả lời của @ DavidLin một chút để đơn giản hóa nó - loại bỏ bất kỳ sự phụ thuộc nào vào jQuery trong chỉ thị. Tôi có thể xác nhận điều này hoạt động khi tôi sử dụng nó trong ứng dụng sản xuất

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

Tôi sử dụng một ng-showthay vì một cuộc gọi jQuery để ẩn / hiện <div>.

Đây là cái <div>mà tôi đã đặt ngay bên dưới <body>thẻ mở :

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

Và đây là CSS cung cấp lớp phủ để chặn giao diện người dùng trong khi lệnh gọi $ http đang được thực hiện:

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

Tín dụng CSS được chuyển đến @Steve Seeger's - bài đăng của anh ấy: https://stackoverflow.com/a/35470281/335545


0

Bạn có thể thêm một điều kiện và sau đó thay đổi nó qua rootcope. Trước yêu cầu ajax của bạn, bạn chỉ cần gọi $ rootScope. $ Release ('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();
                        }
                    });
                }
            };

        }]);

Đây chắc chắn không phải là giải pháp tốt nhất nhưng nó vẫn sẽ hoạt động.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.