【问题标题】:Loader by updating ng-repeat with ng-if通过使用 ng-if 更新 ng-repeat 来加载程序
【发布时间】:2016-04-11 17:49:13
【问题描述】:

首先,这是我的小提琴,所以你可以理解我的问题: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 不正确。因此,不是每次都隐藏加载器并在加载后删除,而是仅在一种情况下将其删除。

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 在文件加载后更新,而不是在我单击时更新,这很奇怪,因为您看不到加载器

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

【问题讨论】:

  • 伙计,如果明天没有答案,我会帮你的。 ;)
  • 谢谢,如果你能帮助我,那就太好了!我目前正在尝试在 ng-repeat 中使用“filter”选项,而不是 ng-if。效果更好:每次都显示“已加载”,但我在等待时看不到加载器
  • 请更新 plunker。 ;)
  • 这是新的:jsfiddle.net/7p3rayjr/1
  • 好的,您找到了解决方案。但是你可以使用 ng-show,而不是 ng-if。但是,在此之前,您可以对数据集进行分页...想想您的用户将如何阅读包含 100.000 条记录的页面...我更喜欢使用“search”和“limitTo”过滤器来保持可用性。

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


【解决方案1】:

经过一段时间,我终于找到了解决方案。我不确定它是不是最好的,但性能更好,加载器也能正常工作。

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

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

由于间隔,我只是每隔几秒增加一次 limitTo,这使得 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/

【讨论】:

  • 蒂姆,我刚回来,很高兴你找到了解决方案。我对你只有一项改进。在这种情况下,您可以使用 ng-if 而不是 ng-show/ng-hide。见jsfiddle.net/7p3rayjr/12ng-if 在设置为 false 时从 dom 中删除标签。而ng-show/ng-hide 只需使用 CSS 将其隐藏即可。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-06
相关资源
最近更新 更多