Показывать цикл прогресса во время публикации $http?

Как лучше всего использовать компонент Angular Material Progress circular с запрос $http?

В настоящее время у меня есть код, подобный этому ниже:

Циркуляр прогресса:

<md-progress-circular ng-if="determinateValue === 100" md-mode="determinate" value="{{determinateValue}}"></md-progress-circular>

$http запрос:

$scope.determinateValue = 0;

$http.get("/posts")
       .success(function (data) {

          $scope.posts = data;
          $scope.determinateValue = 100;

       })

person Michael Wilson    schedule 28.06.2015    source источник
comment
это может помочь вам stackoverflow.com/questions/26116281/   -  person Kalhan.Toress    schedule 28.06.2015
comment
Это должен быть номер material.angularjs.org/ последний/#/api/   -  person Michael Wilson    schedule 28.06.2015
comment
хорошо, тогда поставьте $scope.loading = 1; и $scope.loading = 0; это также будет трактоваться как логические значения true и false   -  person Kalhan.Toress    schedule 28.06.2015
comment
Он ожидает, что вы пройдете весь путь до 100? Наличие $scope.loading = 1; сохранит его в начале material.angularjs.org/ последняя/#/демо/   -  person Michael Wilson    schedule 28.06.2015
comment
Проблема в том, что у вас, похоже, нет номеров для этой задачи. Если бы это были несколько вызовов AJAX, вы могли бы сложить их до процента, но один вызов AJAX в этой абстракции довольно двоичный (0 в начале, 100 в конце, без событий или чисел в середине). Вместо этого вам, вероятно, нужен неопределенный режим для этого конкретного события.   -  person DRobinson    schedule 28.06.2015


Ответы (7)


Я не думаю, что вам нужен атрибут value здесь с режимом determinate. Вместо этого вы должны использовать режим indeterminate, а затем отображать и скрывать индикатор выполнения с помощью ngShow.

<md-progress-circular md-mode="indeterminate" ng-show="isLoading"></md-progress-circular>

И в вашем JS

$scope.isLoading = true;
$http.get("/posts")
   .success(function (data) {
        $scope.isLoading = false;
   });
person Muhammad Reda    schedule 28.06.2015
comment
isLoading должен быть установлен true перед запросом, false после, так как именно тогда он загружается. Если вы измените переменную на isLoaded или hasLoaded, текущее значение true/false будет иметь смысл. Кроме того, и это больше относится к исходному вопросу, вероятно, он должен быть в finally, чтобы индикатор загрузки не вращался вечно при ошибке. - person DRobinson; 28.06.2015
comment
Отлично, это подойдет, это имеет смысл при чтении этого For operations where the user is asked to wait a moment while something finishes up, and it's not necessary to expose what's happening behind the scenes and how long it will take, use an indeterminate indicator. - person Michael Wilson; 28.06.2015
comment
@Майкл Уилсон То же самое :') - person Ravinder Payal; 09.05.2016
comment
как сделать spinner встроенным / встроенным блоком - person Ravinder Payal; 09.05.2016

Если вам нужна версия md-progress-circular, которая также блокирует экран и имеет фон, поместите md-progress-circular внутри mdDialog следующим образом:

     function showWait(){
          $mdDialog.show({
            controller: 'waitCtrl',
            template: '<md-dialog style="background-color:transparent;box-shadow:none">' +
                        '<div layout="row" layout-sm="column" layout-align="center center" aria-label="wait">' +
                            '<md-progress-circular md-mode="indeterminate" ></md-progress-circular>' +
                        '</div>' +
                     '</md-dialog>',
            parent: angular.element(document.body),
            clickOutsideToClose:false,
            fullscreen: false
          })
          .then(function(answer) {

          });
   }

вот плункер, который я создал, который показывает, как плункер

person Post Impatica    schedule 03.02.2016
comment
Это именно то, что мне нужно. Большое спасибо. Все примеры, которые я видел, помещают индикатор прогресса в линию и заставляют другие элементы перемещаться, когда прогресс активируется и деактивируется. Это не сработает для меня. Это делает. Отличная работа. - person Jim Reineri; 22.09.2016

Все ответы верны, просто добавьте еще одну вещь, что $http запрос является асинхронным, который вы должны использовать следующим образом.

$scope.$apply(function(){
$scope.isLoading = false;
});

А в целом вот так

<md-progress-circular md-mode="indeterminate" ng-show="isLoading"></md-progress-circular>

И в вашем JS

$scope.isLoading = истина;

$http.get("/posts")
   .success(function (data) {
         $scope.$apply(function(){
           $scope.isLoading = false;
         });
   });

Примечание. – Источником ответа является принятый ответ.

person Ravinder Payal    schedule 09.05.2016

Вы должны подключиться к событиям $httpProvider:

angular.module('common')
  .config(['$httpProvider', function($httpProvider){
    $httpProvider.interceptors.push(['$rootScope', '$q', '$timeout',
      function($rootScope, $q, $timeout) {
        return {
          request: function(config) {
            $rootScope.posting = new Date().getTime();
            $rootScope.$broadcast('$postingStart', config.url);
            return $q.resolve(config);
          },
          response: function(response) {
            $rootScope.posting = false;
            $rootScope.$broadcast('$postingEnd', response.config.url);
            return $q.resolve(response);
          },
          responseError: function(response) {
            $rootScope.posting = false;
            $rootScope.$broadcast('$postingEnd', response.config.url);
            return $q.reject(response);
          }
        };
      }]);
  }])
.run(['$mdDialog', '$rootScope', function($mdDialog, $rootScope){
  var showing = false;

  function showWait() {
    if(showing) return;
    $mdDialog.show({
      controller: 'waitCtrl',
      template: '<md-dialog id="plz_wait" style="background-color:transparent;box-shadow:none">' +
      '<div layout="row" layout-sm="column" layout-align="center center" aria-label="wait">' +
      '<md-progress-circular md-mode="indeterminate" ></md-progress-circular>' +
      '</div>' +
      '</md-dialog>',
      parent: angular.element(document.body),
      clickOutsideToClose: false,
      fullscreen: false
    })
      .then(function(answer) {
        showing = false;
      });
  }


  $rootScope.$on('$postingStart', function(event, url) {
    if (!$rootScope.postingStartTimer) {
      $rootScope.postingStartTimer = $timeout(function() {
        showWait()
      }, 250);
    }
  });

  $rootScope.$on('$postingEnd', function(event, url) {
    if ($rootScope.postingStartTimer && posts.length === 0) {
      $timeout.cancel($rootScope.postingStartTimer);
      $rootScope.postingStartTimer = false;
      if(!showing) return;
      $mdDialog.cancel();
    }
  });

}])
person malix    schedule 05.07.2016
comment
Я попробовал эту версию, которая выглядит хорошо, но $timeout отсутствует, и там написано, что posts не определено. - person Onestone; 07.12.2016

Я надеюсь, что этот код поможет.

  var isLoadingShown = false;

  $scope.$watch(function() {
    return $http.pendingRequests.length;
  }, 
  function(newValue, oldValue) {
    console.log(newValue);
    if(newValue !== 0) {
      if(!isLoadingShown) {
        showLoading();         
      }
    }
    else hideLoading();
  });

  function showLoading(){
    isLoadingShown = true;   
    $mdDialog.show({
      template: '<md-dialog style="background-color:transparent;box-shadow:none;overflow: hidden !important;">' +
                  '<div layout="row" layout-sm="column" layout-align="center center" aria-label="wait">' +
                    '<md-progress-circular class="md-hue-2" md-diameter="50px"></md-progress-circular>' +
                  '</div>' +
                '</md-dialog>',
      parent: angular.element(document.body),
      clickOutsideToClose:false,
      escapeToClose: false,
      fullscreen: false
    });
  }

  function hideLoading(){
    $mdDialog.cancel();
    isLoadingShown = false; 
  }
person Fatih Turgut    schedule 09.05.2017
comment
это действительно хорошо, но нажатие ESC отменяет диалог, поэтому вы должны добавить также «escapeToClose: false» в конфигурацию mdDialog - person Doru Chiulan; 08.08.2017
comment
Спасибо @DoruChiulan. я добавил. - person Fatih Turgut; 14.08.2017

Сначала установите какую-нибудь модель:

$scope.loading=false;

Привяжите эту модель к свойству ng-show элемента progress round:

<md-progress-circular ng-show="loading" md-mode="indeterminate"></md-progress-circular>

Установите для него значение true перед вызовом запроса $http и установите значение false для $http .success:

$scope.loading=true;

$http.get("/posts")
   .success(function (data) {

      $scope.posts = data;

      $scope.loading=false;

   })

Надеюсь, это поможет.

person Tomislav    schedule 28.06.2015
comment
Разве цикл прогресса не должен быть числом? material.angularjs.org/latest/#/api/ - person Michael Wilson; 28.06.2015
comment
Я отредактировал свой ответ. ng-show повлияет только на видимость html-элемента (true — видимый, false — скрытый). Присвойте значение $scope.determinateValue в обратном вызове успеха $http перед вызовом load=false, и все готово. - person Tomislav; 28.06.2015
comment
Согласно документации вам не нужен детерминированный режим в md-progress-circular. Просто поставь его неопределенным. Я отредактировал свой ответ соответственно. - person Tomislav; 28.06.2015

Если вы хотите следить за ходом обработки данных, используйте uploadEventHandlers.

Есть пример.

$http({
    method: 'POST',
    url: '/uploadToFtp',
    headers: {
        'Content-Type': undefined
    },
    eventHandlers: {
        progress: function(c) {
            //console.log('Progress -> ' + c);
            //console.log(c);
        }
    },
    uploadEventHandlers: {
        progress: function(e) {
            //console.log('UploadProgress -> ' + e);
            //console.log(e);
            _self.progressValue = (e.loaded / e.total) * 100.0;
        }
    },
    data: postData,
    transformRequest: angular.identity
})
.then(callBack,errorCallBack)
.catch(errorCallBack);

Покажите циркуляр прогресса, как это

<md-progress-circular ng-if="ctrl.progressValue > 0 && ctrl.progressValue < 100" md-mode="determinate" value="{{ctrl.progressValue}}"></md-progress-circular>
person Burak Akyıldız    schedule 09.05.2017