【问题标题】:Show progress circular during $http post?在 $http 发布期间显示进度通知?
【发布时间】:2015-09-15 01:29:24
【问题描述】:

将 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;

       })

【问题讨论】:

  • ok 然后把 $scope.loading = 1;$scope.loading = 0; 这也视为布尔值 truefalse
  • 它希望你一直到 100?拥有$scope.loading = 1; 将在开始时保持material.angularjs.org/latest/#/demo/…
  • 问题是你似乎没有这个任务的编号。如果是多个 AJAX 调用,您可以将它们加到一个百分比,但是在这个抽象中的单个 AJAX 调用是相当二进制的(开始时为 0,结束时为 100,中间没有事件或数字)。相反,您可能需要此特定事件的“不确定”模式。

标签: javascript angularjs angular-material


【解决方案1】:

如果您想要一个 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) {

          });
   }

这是我创建的一个 plunker,它显示了如何 Plunker

【讨论】:

  • 这正是我所需要的。太感谢了。我见过的所有示例都将进度指示器排成一行,并在激活和停用进度时使其他元素四处移动。那对我不起作用。这样做。干得好。
【解决方案2】:

我认为您不需要 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;
   });

【讨论】:

  • isLoading 应该在请求之前设置true,在之后设置false,因为那是它加载的时候。如果您将变量更改为isLoadedhasLoaded,则当前的真/假是有意义的。此外,这更多地与原始问题有关,它可能应该在finally 中,以防止加载指示器因错误而永远旋转。
  • 这很好,阅读这篇文章很有道理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.
  • @MichaelWilson Ditto :')
  • 如何制作spinner inline / inline-block
【解决方案3】:

所有答案都是正确的,只需再添加一件事,$http 请求是异步的,您应该像这样使用

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

整体就是这样

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

在你的 JS 中

$scope.isLoading = true;

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

注意:-答案的来源是接受的答案。

【讨论】:

    【解决方案4】:

    你应该联系$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();
        }
      });
    
    }])
    

    【讨论】:

    • 我试过这个版本,看起来不错,但是缺少 $timeout 并且它说 posts 未定义。
    【解决方案5】:

    我希望这段代码有所帮助。

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

    【讨论】:

    • 真的很好,但是按 ESC 会取消对话框,所以你应该在 mdDialog 配置中添加 'escapeToClose: false'
    • 谢谢@DoruChiulan。我加了。
    【解决方案6】:

    先设置一些模型:

    $scope.loading=false;
    

    将该模型与进度循环元素 ng-show 属性绑定:

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

    在调用 $http 请求之前将其设置为 true,并在 $http .success 上将其设置为 false:

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

    希望对您有所帮助。

    【讨论】:

    • 进度通知不需要是数字吗? material.angularjs.org/latest/#/api/…
    • 我已经编辑了我的答案。 ng-show 只会影响 html 元素的可见性(真 - 可见,假 - 隐藏)。在调用 loading=false 之前,在 $http 成功回调中为 $scope.determinateValue 赋值,一切顺利。
    • 根据文档,您不需要 md-progress-circular 中的确定模式。只是把它不确定。我相应地编辑了我的答案。
    【解决方案7】:

    如果您想查看发布数据的进度,请使用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>
    

    【讨论】:

      猜你喜欢
      • 2014-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-04
      • 1970-01-01
      • 2018-12-08
      相关资源
      最近更新 更多