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