AngularJS懒渲染(不懒加载意见)
比方说,我有我想渲染(在ng-repeat
)与固定高度和overflow: auto
一个div项目的大量(3000+),所以我会得到N
可见项目和其他人的滚动条。AngularJS懒渲染(不懒加载意见)
我猜想做一个简单的ng-repeat
有这么多的项目可能会花费很多时间。有没有办法让AngularJS只呈现那些可见的N
项目?
编辑:
的无限滚动是不是我想要的。我希望用户能够滚动到列表中的任何一点,所以我实际上需要类似于文本编辑器的行为。换句话说:我希望卷轴能够包含所有项目的“高度”,但只能放在DOM中的几个。
扩大格兰迪的使用点
.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>
这个答案提供了懒渲染唯一项目,目前视,由编辑到原来的问题中定义的方法。 我希望用户能够滚动到列表中的任何一点,所以我实际上需要类似文本编辑器的行为。换句话说:我希望卷轴能够包含所有项目的“高度”,但只能放在DOM中的几个。
在尝试此操作前安装angular-inview
插件。
为了获得你的scrollheight,你需要一些东西为你的数组项目保留空间。所以我想用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];
}
}
});
,我会给你的内容的占位符看起来像预渲染。使用ng-if
将防止渲染逻辑被不必要地运行。当您将一个项目滚动到视图中时,它会自动显示。如果您想等待一秒以查看用户是否仍在滚动,则可以在loadItem
方法中设置超时,如果在合理的时间段内将相同的索引推出视图,该方法将取消。
注:如果你真的想避免将任何在DOM中,你可以在你的滚动区域设置为你的“占位”高度的特定倍数。然后,您可以创建一个指令,使用该高度来确定应显示的项目的索引。只要您展示新项目,您需要将其高度添加到总数中,并确保将其定位在正确的位置,并确保您的指令知道如何将这些高度解释为评估下一组显示元素。但我认为这太激进和不必要了。
如果'inview'需要评估3000个元素中的每一个是否可见,那么这不会使整个事情变得非常缓慢? – alexandernst
我还没有检查此解决方案的性能。但是我们正在谈论一个妥协,因为我假设你的问题渲染逻辑非常重。 inview指令做了一个非常基本的数学检查,并没有进行任何渲染。这些集合仅限于你所看到的,所以我的猜测是,即使有3000个比较,你也不会看到一个激进的效果。你必须运行一些指标,看看哪一天更快。 –
您也可以分叉指令并添加一些限制,以便逐步检查。如果您以线性方式显示元素,则您将知道基于最后一个滚动位置和滚动方向可以忽略哪些元素,在这种情况下,您只需要沿一个方向迭代,直到找到某个项目不在视图中并可以停止。 –
你可以简单的切片数组为ng-repeat,你需要计数 – Grundy
@Grundy什么是我需要的?如果我只是“重复”N个元素而不是所有元素,我将如何拥有一个滚动条?我的意思是......我不确定你确切地明白我在问什么。你能重读我的问题吗? – alexandernst
例如:你有3000个项目的集合,首先你做的事情是:'arrForShow = items.slice(0,20)',然后在滚动上添加项目到'arrForShow'并为此做'ng-repeat' – Grundy