2015-10-18 65 views
0

比方說,我有我想渲染(在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

回答

0

擴大格蘭迪的使用點.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

1

這個答案提供了懶渲染唯一項目,目前視,由編輯到原來的問題中定義的方法。 我希望用戶能夠滾動到列表中的任何一點,所以我實際上需要類似文本編輯器的行爲。換句話說:我希望卷軸能夠包含所有項目的「高度」,但只能放在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

您也可以分叉指令並添加一些限制,以便逐步檢查。如果您以線性方式顯示元素,則您將知道基於最後一個滾動位置和滾動方向可以忽略哪些元素,在這種情況下,您只需要沿一個方向迭代,直到找到某個項目不在視圖中並可以停止。 –