how to show only 25 element at one time?

2019-08-10 17:56发布

I am trying make table view in ionic using angular js .but I have lot of data to show around 5000 object .So after getting data my UI hang because it is printing the data on dom.So I want to implement lazy loading so that only 100 element is visible to me or only 100 element present in dom only .When user scroll it download another 100 objects or element and removing the uppers element so that my UI not hang .can we do in angular js I will show you how my UI hang .take a look my example here

my loader hang for around 5 seconds ..

So I tried with infinite scroll in my demo so that I am able to show only 100 element at one time

here is my code of infinite scroll But I am not able to display 100 element at one time I didnot get any error also

  <ion-infinite-scroll ng-if="!noMoreItemsAvailable" on-infinite="canWeLoadMoreContent()" distance="10%">
      <div class="row" ng-repeat="column in _list | orderBy: sortval:reverse | filter: query">
        <div class="col col-center brd collapse-sm" ng-repeat="field in column.columns" ng-show="invoice_column_name['index'].fieldNameOrPath===field.fieldNameOrPath">{{field.value}}</div>
        <div class="col col-10 text-center brd collapse-sm"></div>
      </div>
      </ion-infinite-scroll>
    </ion-content>

4条回答
做自己的国王
2楼-- · 2019-08-10 18:22

You need to set up a pagination rather than use infinite scroll; or keep the functionnality of infinite scroll as is.

but if you wish to still use infinite scroll, then when you load your next datas into _list, just before filling in the new elements, clean your _list with a _list.length= 0

But you will have sideeffects that I don't know such as : - how to load the 100 first elements ? - the page will jump from full with 100 elements, cleaned to 0, and filled with next 100. This will lead, I assume, to an unpleasant effect

My configuration of ion-infinite is the following :

  <ion-infinite-scroll     
    ng-if="!myModel.maxItemLoaded"
    icon="ion-loading-c"
    on-infinite="loadMoreData()"
    distance="10"
  >

Which means : - when user scroll gets on the 10 last % of the page height, loads loadMoreData

If user never scoll, then he has only the first data shown.

Edit: Here is an updated plunkr http://plnkr.co/edit/B5KCbc8hr66upCXMvXSR?p=preview

Few remarks : - the infinite scroll directive is independent and shall not surroung your table - accessing to to index is done by $index, not with 'index' - the load functionnality has been modified to load the next 100 elements

$scope.populateList = function() {
        var size = $scope._list.length;
        var maxSize = size + 100;
        if (maxSize > $scope.invoice_records.length)
          maxSize = $scope.invoice_records;
          console.log("populateList",size,maxSize,$scope.invoice_records)
        for (var i = size; i <= maxSize; i++) {
          console.log("push",$scope.invoice_records[i])
          $scope._list.push($scope.invoice_records[i]);
        }    
        console.log($scope._list.length);
        $scope.$broadcast('scroll.infiniteScrollComplete');    
      }
查看更多
SAY GOODBYE
3楼-- · 2019-08-10 18:27

Angular should work with 5000 object, if it is read only , you can use one time binding

An expression that starts with :: is considered a one-time expression. One-time expressions will stop recalculating once they are stable, which happens after the first digest if the expression result is a non-undefined value (see value stabilization algorithm below).

<span ng-bind="::name"></span>


I don't know infinite scrolling, but if I had to implement something like that i would have used ng-filter 'limit'.

ng-repeat="column in _list | limit : limitValue"

And then bind any button/scroll event to

$scope.limitValue = $scope.limitValue + "10";

查看更多
放荡不羁爱自由
4楼-- · 2019-08-10 18:42

Ideally you should not have brought this much data in 1 call. Now, if you have, you can achieve this by a small tweak.

Break your data in chunk of 100. And set that 100 in $scope.

var brokenData = [];
var totalData = x; // Total 5000 records
var pages = parseInt(totalData.length/100);
if(totalData.length % 100 !== 0) {
    pages += 1;
}
for (var i = 0; i < pages; i++){
    if(i == pages - 1) {
        brokenData.push(totalData);
    } else {
        brokenData.push(totalData.splice(0,100));
    }
}

Now set

$scope.pages = pages; 

And for 1st page or for 1st time,

$scope.pageData = brokenData[0];
$scope.currentPage = 0 + 1;

This will show only 100 records on your page and sets current page as 1.

Now you can choose any pagination tool or bind window scroll events and just update the above 2 things

Like for 2nd page

$scope.pageData = brokenData[1];
$scope.currentPage = 1 + 1;
查看更多
兄弟一词,经得起流年.
5楼-- · 2019-08-10 18:44

Updated Plunker

I took a little different approach then the others.

There is a variable at the top of the controller called showitems. This controls how many items you want to show at a time. The counter variable will keep track of where how many items are shown. Initially, the value is set to the showitems value since we're going to prepopulate the dataset with the first items immediately in the ShowViewAfterSuccess function.

var showitems = 100;
var counter = showitems;

In your ShowViewAfterSuccess function, I added the data to a scope variable called $scope.total_invoice_records.

Next, I run the first array slice on the data. This will pass the first x number of records to the $scope.invoice_records based on the value set in the showitems variable. This initializes the view with the first set of records.

$scope.total_invoice_records=data.records;
$scope.invoice_records = $scope.total_invoice_records.slice(0, showitems);

I added a loadMore function that simply grabs the next x number of records from the total record set and concatenates them to the current set in $scope.invoice_records and increments the counter. loadMore will also check if there are still more records to load and broadcasts the message to the ionic infinite scroll directive to remove the spinner.

  $scope.noMoreItemsAvailable = false;
  $scope.loadMore = function() {
    var next = $scope.total_invoice_records.slice(counter, counter+showitems);
    $scope.invoice_records = $scope.invoice_records.concat(next);
    counter = counter+showitems;
    if (counter>=$scope.total_invoice_records.length) {
      $scope.noMoreItemsAvailable = true;
    }
    $scope.$broadcast('scroll.infiniteScrollComplete');
  };

Most importantly, remember to set the immediate-check attribute on the infinite scroll element to false:

<ion-infinite-scroll immediate-check="false" ng-if="!noMoreItemsAvailable" on-infinite="loadMore()" distance="10%"></ion-infinite-scroll>
查看更多
登录 后发表回答