AngularJS懒渲染(不懒加载意见)

问题描述:

比方说,我有我想渲染(在ng-repeat)与固定高度和overflow: auto一个div项目的大量(3000+),所以我会得到N可见项目和其他人的滚动条。AngularJS懒渲染(不懒加载意见)

我猜想做一个简单的ng-repeat有这么多的项目可能会花费很多时间。有没有办法让AngularJS只呈现那些可见的N项目?

编辑:

的无限滚动是不是我想要的。我希望用户能够滚动到列表中的任何一点,所以我实际上需要类似于文本编辑器的行为。换句话说:我希望卷轴能够包含所有项目的“高度”,但只能放在DOM中的几个。

+0

你可以简单的切片数组为ng-repeat,你需要计数 – Grundy

+0

@Grundy什么是我需要的?如果我只是“重复”N个元素而不是所有元素,我将如何拥有一个滚动条?我的意思是......我不确定你确切地明白我在问什么。你能重读我的问题吗? – alexandernst

+0

例如:你有3000个项目的集合,首先你做的事情是:'arrForShow = items.slice(0,20)',然后在滚动上添加项目到'arrForShow'并为此做'ng-repeat' – 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> 
+0

请检查我的编辑。 – alexandernst

+0

@alexandernst,非常有趣。你的物品是固定的高度吗? –

+0

不,他们可以有不同的身高。 – alexandernst

这个答案提供了懒渲染唯一项目,目前视,由编辑到原来的问题中定义的方法。 我希望用户能够滚动到列表中的任何一点,所以我实际上需要类似文本编辑器的行为。换句话说:我希望卷轴能够包含所有项目的“高度”,但只能放在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中,你可以在你的滚动区域设置为你的“占位”高度的特定倍数。然后,您可以创建一个指令,使用该高度来确定应显示的项目的索引。只要您展示新项目,您需要将其高度添加到总数中,并确保将其定位在正确的位置,并确保您的指令知道如何将这些高度解释为评估下一组显示元素。但我认为这太激进和不必要了。

+0

如果'inview'需要评估3000个元素中的每一个是否可见,那么这不会使整个事情变得非常缓慢? – alexandernst

+0

我还没有检查此解决方案的性能。但是我们正在谈论一个妥协,因为我假设你的问题渲染逻辑非常重。 inview指令做了一个非常基本的数学检查,并没有进行任何渲染。这些集合仅限于你所看到的,所以我的猜测是,即使有3000个比较,你也不会看到一个激进的效果。你必须运行一些指标,看看哪一天更快。 –

+0

您也可以分叉指令并添加一些限制,以便逐步检查。如果您以线性方式显示元素,则您将知道基于最后一个滚动位置和滚动方向可以忽略哪些元素,在这种情况下,您只需要沿一个方向迭代,直到找到某个项目不在视图中并可以停止。 –