通过ng-if更新ng-repeat的加载器

时间:2016-04-11 17:49:14

标签: javascript angularjs angularjs-ng-repeat loader angular-ng-if

首先,这是我的小提琴,所以你可以理解我的问题:https://jsfiddle.net/860Ltbva/5/

我想在加载循环ng-repeat时显示加载消息,并在加载所有元素时隐藏它。

我用这个小提琴帮助:http://jsfiddle.net/jwcarroll/ZFp3a/

此代码使用指令来了解何时加载最后一个元素:

app.directive("repeatEnd", function() {
  return {
    restrict: "A",
    link: function(scope, element, attrs) {
      if (scope.$last) {
        scope.$eval(attrs.repeatEnd);
      }
    }
  };
});

第一个问题:

这项工作只有在我加载每个元素时,但我使用ng-if来过滤它,这就是我遇到一些问题的地方。因为如果未加载最后一个元素,则$ scope。$ last不为true。因此,不是每次都隐藏加载器而是在加载后删除它,而是仅在一种情况下删除它。

HTML:

<div class="test" ng-repeat="light in lights" ng-if="showLights(light.status)" repeat-end="onEnd()">
<span>{{light.name}} - {{light.status}}</span></div>

控制器:

app.controller("MyCtrl", function($scope, $timeout) {
  $scope.lights = [];
  $scope.loadingPatients = true;
  $scope.showStatus = 'on';

 for (var x = 0; x < 10000; x=x+2) {
    $scope.lights[x] = {'name': 'kitchen', 'status':'off'};
    $scope.lights[x+1] = {'name': 'living room', 'status':'on'};
  }

  $scope.showStatusFct = function(status){
    $scope.loadingPatients = true;
    $scope.showStatus = status;
  };
  $scope.showLights = function(lightStatus) {
    if ($scope.showStatus == 'on') {
      if (lightStatus == 'on')
        return true;
    } else {
      if (lightStatus == 'off')
        return true;
    }
  }

  $scope.onEnd = function() {
    $scope.loadingPatients = false;
  };

});

第二个问题

变量$ scope.loadingPatients在文件加载后更新,而不是在我点击后立即更新,这很奇怪,因为你看不到加载器

对这些问题有什么想法吗? 感谢

1 个答案:

答案 0 :(得分:0)

过了一会儿,我终于找到了解决方案。我不确定它是最好的,但性能更好,装载机工作。

为此,我使用了角度的$ interval方法,并在ng-repeat循环中使用了filter和limitTo。我终于删除了ng-if。

这是新的小提琴:https://jsfiddle.net/timguignard/7p3rayjr/11/

我只是每隔几秒就增加一次限制,这要归功于间隔,这使得ng-repeat变得更快,并且还使装载机工作。并且一旦页面加载就开始加载,你不会在开始时看到ng-repeat冻结。

我的最后建议实际上不是使用太长的ng-repeat,而是将limitTo用于最大值。在该示例中,limitTo等于对象的长度,但是如果我放置了100,000个对象,则在更改过滤器时,它仍会使应用程序冻结片刻。如果我将最大值设置为1,000或甚至10,000,您将看不到它冻结。

以下是代码:

HTML

<div ng-controller="MyCtrl">
  <button ng-click="upFilter('on')">Show lights ON</button>
  <button ng-click="upFilter('off')">Show lights OFF</button>

  <div ng-show="loadingWait">==LOADING==</div>
  <div ng-hide="loadingWait">==LOADED==</div>
  Limit lights: {{limitLights}} - Max all lights: {{maxLights}}

  <div class="test" ng-repeat="light in lights | filter : filter | limitTo:limitLights">
      <span>{{light.name}} - {{light.status}}</span>
   </div>
</div>

和Javascript

(function() {
    angular.element(document).ready(function() {
    var app = angular.module('myApp', []);

    app.controller("MyCtrl", function($scope, $interval) {
      $scope.lights = [];
      $scope.loadingWait = true;

      //set the data
      for (var x = 0; x < 10000; x = x + 2) {
        $scope.lights[x] = {
          'name': 'kitchen',
          'status': 'off'
        };
        $scope.lights[x + 1] = {
          'name': 'living room',
          'status': 'on'
        };
      }
      $scope.maxLights = $scope.lights.length;

      $scope.upFilter = function(stat) {
        $scope.loadingWait = true;
        $scope.filter = {
          status: stat
        };
        loading();
      }
      loading();

      //login with interval
      var myInterval;

      function loading() {
        $scope.loadingWait = true;
        $scope.limitLights = 1;
        myInterval = $interval(function() {
          if ($scope.limitLights > $scope.lights.length) {
             $interval.cancel(myInterval);
             myInterval = undefined;
             $scope.loadingWait = false;
          }
          $scope.limitLights += 1000;
        }, 100)
      }
    });

   //to make the fiddle work
   angular.bootstrap(document, ['myApp']);
  });
}());

希望如果有人需要它可以提供帮助。如果您有更好的解决方案,请随时分享,我会检查它!

我也找到了这个小提琴,似乎使用了更好的选择。我也会尝试检查它:http://jsfiddle.net/nikospara/b8thjobp/