2013-06-17 2 views
104

Используя Angularjs, мне нужно показать экран загрузки (простой счетчик) до тех пор, пока не будет завершен запрос ajax. Пожалуйста, предложите любую идею с фрагментом кода.Экран загрузки Angularjs по запросу ajax

+4

см. Http://stackoverflow.com/questions/15033195/showing-spinner-gif-during-http-request-in-angular –

+2

http://angulartutorial.blogspot.in/2014/04/ angular-loader-using-font-awesome-icons.html – Prashobh

+0

Лучшая практика заключается в использовании '$ httpProvider.interceptors', поскольку она может обрабатывать, когда запускается запрос ajax и когда он заканчивается. Вот почему '$ watch' больше не требуется, чтобы обнаруживать, когда начало и конец запуска ajax. –

ответ

197

Вместо создания видимости переменных для отображения состояния загрузки данных, то лучше иметь директиву делает все для вас:

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

    }]); 

С помощью этой директивы, все, что вам нужно сделать, это дать никакой нагрузки анимационный элемент и атрибут «погрузки»:

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

На странице может быть несколько загрузочных прядильщиков. где и как правильно расположить эти прядильщики, и директива просто включит/выключит вас автоматически.

+0

здесь директива "loading" вызывается дважды, с $ location.path(). Сначала с текущей страницей и рядом с целевой страницей. В чем причина? –

+0

Отлично. Кроме того, вы можете использовать jquery toggle на watch: elm.toggle (v). У меня есть контрольный сеанс сеанса ожидания, и для меня мне нужно показать счетчик только через полсекунды. Я буду использовать css с переходом, чтобы медленнее показывать счетчик. –

+7

Если вы получаете ошибку «elm.show() не является функцией», перед загрузкой нужно добавить jquery. – morpheus05

54

Вот пример. Он использует простой метод ng-show с 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; 
    }); 
    } 

Конечно, вы можете переместить HTML-код загрузки коробки в директиву, а затем использовать $ смотреть на $ scope.loading. В этом случае:

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

шлепнуть: http://plnkr.co/edit/AI1z21?p=preview

+3

Спасибо, что разделили примеры директив - хорошо ответ на общий подход :) – kontur

+0

То, как вы делаете scope.watch, работает для меня, потому что принятый подход ответа не делает. – KingOfHypocrites

+0

Работает отлично. Престижность за подробное объяснение! – Gene

2

Также есть хороший демо, что показывает, как можно вы используете Angularjs анимация в вашем проекте.
Ссылка есть
http://yearofmoo-articles.github.io/angularjs-animation-article/app/#/ng-repeat (См. Верхний левый угол).
Это открытый источник. вот ссылка для скачивания
https://github.com/yearofmoo-articles/AngularJS-Animation-Article
И вот ссылка для учебника;
http://www.yearofmoo.com/2013/04/animation-in-angularjs.html
Я хочу сказать, продолжайте и загрузите исходные файлы, а затем посмотрите, как они реализовали счетчик. Возможно, они использовали немного лучше. Итак, проверьте этот проект.

6

Лучший способ сделать это - использовать ответные перехватчики вместе с пользовательским директивой. И этот процесс можно дополнительно улучшить, используя pub/sub механизм с использованием $ rootScope. $ Broadcast & $ rootScope. $ On методы.

Как весь процесс документирован в хорошо написанном blog article, я не буду повторять это здесь снова. Пожалуйста, обратитесь к этой статье, чтобы придумать необходимую вам реализацию.

19

Я использую ngProgress для этого.

Добавьте 'ngProgress' к вашим зависимостям, как только вы включили файлы сценария/css в свой HTML. После этого вы можете настроить что-то вроде этого, которое будет срабатывать при обнаружении изменения маршрута.

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, используйте инкрементную переменную в основной области приложения, чтобы отслеживать, когда ваши запросы AJAX завершились до вызова 'ngProgress.complete();'.

+1

Wow. Это фантастика. Спасибо. – Fortin

13

с использованием ожидающих запросов Requests неверен, поскольку, как указано в Угловой документации, это свойство в основном предназначено для использования в целях отладки.

Я рекомендую использовать перехватчик, чтобы узнать, есть ли активный Асинхронный вызов.

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

, а затем проверить, является ли activeCalls нулевым или нет в директиве через $ 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(); 
       } 
      }); 
     } 
    }; 
}); 
2

Если вы используете 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; 
     }); 
     } 
    }; 
    }) 
; 
+0

Любой ответ API будет убивать анимацию. Вы должны хранить дополнительную информацию о запросе-ответе и реагировать только на тот ответ, который был инициализирован по запросу. –

2

Включите это в "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); 
    } 
    }; 
}); 
3

В отношении этого ответа

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>

Вам нужно заменить $ (элемент) .show(); и (element) .show(); с $ scope.loadingStatus = 'true'; и $ scope.loadingStatus = 'false';

Чтобы использовать атрибут ng-show элемента, вам необходимо использовать эту переменную.

3

Машинопись и Угловое Реализация

директива

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

Благодарим вас за это! Примеры js раздражают, чтобы перевести ... – daark

+0

Вы спасли мой день, спасибо! :) – Lightning3

1

Использование angular-busy:

Добавить 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> 
0

Я построил на @ DavidLin ответ немного, чтобы упростить его - удаляя любую зависимость от jQuery в директиве. Я могу подтвердить, что это работает, как я использую его в приложении производства

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-show вместо вызова JQuery, чтобы скрыть/показать <div>.

Вот <div>, который я поставил чуть ниже отверстия <body> тег:

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

И вот CSS, который обеспечивает наложение блокировать пользовательский интерфейс в то время как $ HTTP вызов был сделан:

.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

1

Здесь простой пример перехватчика, я установил мышь в ожидании w При запуске 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, которые показывают загрузчик.

Interceptor будет запускаться при каждом вызове ajax, поэтому нет необходимости создавать специальные булевы переменные ($ scope.loading = true/false и т. Д.) Для каждого HTTP-вызова.

Перехватчик использует встроенный угловой jqLitehttps://docs.angularjs.org/api/ng/function/angular.element так что нет необходимости в JQuery.

1

Создать директиву с шоу и размера атрибутов (вы можете добавить еще больше)

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> 

В показать прохода переменной истинное когда любое обещание выполняется и делает это false, когда запрос будет выполнен. Активный демо - Angular Loader directive example demo in JsFiddle

0

Вы можете добавить условие, а затем изменить его с помощью rootscope. Перед вашим запросом 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(); 
         } 
        }); 
       } 
      }; 

     }]); 

Это определенно не самое лучшее решение, но он все равно работает.

Смежные вопросы