[英]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.