簡體   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