繁体   English   中英

AngularJS延迟渲染(不延迟加载视图)

[英]AngularJS lazy rendering (not lazy loading views)

假设我有很多(3000+)项要在div中呈现(固定在ng-repeat ),且高度固定且overflow: auto ,因此我将获得N可见项和一个滚动条,以供其余部分使用他们。

我猜测对这么多项目执行简单的ng-repeat可能会花费很多时间。 有没有办法让AngularJS仅渲染那些可见的N项目?

编辑:

无限滚动不是我想要的。 我希望用户能够滚动到列表的任何点,因此我确实希望获得类似文本编辑器的行为。 换句话说:我希望滚动条包含所有项目的“高度”,但在DOM中只放置其中一些。

根据对原始问题的编辑定义,此答案提供了一种仅对当前正在查看的项目进行延迟渲染的方法。 我希望用户能够滚动到列表的任何点,因此我确实希望获得类似文本编辑器的行为。 换句话说:我希望滚动条包含所有项目的“高度”,但在DOM中只放置其中一些。

在尝试此之前,请先安装angular-inview插件。

为了获得滚动高度,您需要一些东西来容纳数组项的空间。 因此,我将从3000个简单项目的数组开始(或与无限滚动结合到所需的任意程度。)

var $app = angular.module('app', ['infinite-scroll']);

$app.controller('listingController', function($scope, $window) {
  $scope.listOfItems = new Array($window._bootstrappedData.length);
  $scope.loadItem = function($index,$inview) {
    if($inview) {
      $scope.listOfItems[$index] = $window._bootstrappedData[$index];
    }
  }
});

由于我们在谈论灵活的高度,因此我将为您的内容看起来像预渲染的内容创建一个占位符。

<div ng-controller="listingController">
  <ul>
    <li ng-repeat="item in listOfItems track by $index" in-view="loadItem($index,$inview)" style="min-height:100px"><div ng-if="item">{{item.name}}</div></li>
  </ul>
</div>

使用ng-if可以防止渲染逻辑不必要地运行。 将项目滚动到视图中时,它将自动显示。 如果要等待一秒钟以查看用户是否仍在滚动,则可以在loadItem方法中设置一个超时,如果在合理的时间段内将同一索引推出视图,该方法将取消。

注意:如果您确实想避免在DOM中放置任何内容,则可以将可滚动区域设置为“占位符”高度的特定倍数。 然后,您可以创建一个指令,使用该高度确定应该显示的项目的索引。 显示新项目时,需要将它们的高度加到总计中,并确保将它们放置在正确的位置,并确保您的指令知道如何解释这些高度以评估下一组显示的元素。 但是我认为这太过激进和不必要了。

扩展Grundy关于使用.slice()的观点。

当我需要延迟渲染/延迟加载数据时,我使用ngInfiniteScroll

我会保留那些3000条记录你的范围,以防止不必要的拖累你的消化性能,然后将它们添加到您的示波器数据,你需要他们。 这是一个例子。

var $app = angular.module('app', ['infinite-scroll']);

$app.controller('listingController', function($scope, $window) {

  /*
   * Outside of this controller you should bootstrap your data to a non-digested array.
   * If you're loading the data via Ajax, save your data similarly.
   * For example:
   * <script>
   *   window._bootstrappedData = [{id:1,name:'foo'},{id:2,name:'bar'},...];
   * </script>
   */
  var currentPage, pageLength;
  $scope.listOfItems = [];
  currentPage = 0;
  pageLength = 100;
  $scope.nextPage = function() {
    // make sure we don't keep trying to slice data that doesn't exist.
    if (currentPage * pageLength >= $window._bootstrappedData.length) {
      return false;
    }

    // append the next data set to your array
    $scope.listOfItems.push($window._bootstrappedData.slice(currentPage * pageLength, (currentPage + 1) * pageLength));
    currentPage++;
  };

  /*
   * Kickstart this data with our first page.
   */
  return $scope.nextPage();
});

和您的模板:

<div ng-controller="listingController" infinite-scroll="nextPage()" infinite-scroll-distance="3">
  <ul>
    <li ng-repeat="item in listOfItems">{{item.name}}</li>
  </ul>
</div>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM