Erkan Demir
Erkan Demir

Reputation: 795

Angular JS ngInfiniteScroll with LimitTo

I'm using ngInfiniteScroll ng-module for my pagination. When i scroll down the page i'm appending 20 records to my data table. By doing that, i'm actually running a http request each time ("not good for performance).

I've been doing some research and came across adding a LimitTo with the ngInfiniteScroll. Not sure how to implement this. Could someone please give me any suggestions.

   <table infinite-scroll='tF.loadMore()' infinite-scroll-disabled='tF.isBusy' infinite-scroll-distance='3' class="responsive">
            <thead>
                <tr>
                    <th>FIRST NAME</th>
                    <th>LAST NAME</th>
                    <th>USERNAME</th>
                    <th>EMAIL</th>
                    <th>CREATED DATE</th>
                    <th>STATUS</th>
                    <th>IS ONLINE</th>
                    <th>ACTIONS</th>
                </tr>
            </thead>
            <tbody>
                <tr ng-repeat="item in tF.items | filter:searchFilter">
                    <td>{{item.FirstName}}</td>
                    <td>{{item.LastName}}</td>
                    <td>{{item.Username}}</td>
                    <td>{{item.Email}}</td>
                    <td>{{item.CreatedDate | date:'medium'}}</td>
                    <td></td>
                    <td></td>
                    <td></td>
                </tr>
            </tbody>
            <tfoot ng-show='tF.isBusy'>
                <tr>
                    <td colspan="9"><spinner show="tF.isBusy" /><span class="bold">{{tF.status}}</span> </td>
                </tr>
            </tfoot>
        </table>

/**** CONTROLLER.JS *****/

    var vm = this;
    var page = 0;
    vm.items = [];
    vm.isBusy = false;

    vm.loadMore = function ()
    {
        if(vm.isBusy) return;
        vm.isBusy = true;

        userService.GetAllRecords(page)
        .success(function (data)
        {
            var results = data;

            for (var i = 0; i < results.length; i++)
            {
                vm.items.push(results[i]);
            }

            page++;
            vm.isBusy = false;

        }.bind(vm))
        .error(function (error)
        {
            vm.status = 'Error retrieving data! ' + error.message;
        })
        .finally(function ()
        {
            vm.isBusy = false;
        });
    }

Upvotes: 1

Views: 1658

Answers (2)

devqon
devqon

Reputation: 13997

You could load all data once, and append pieces while scrolling:

var vm = this;
var page = 0;
vm.currentItems = [];
var allData = [],
    step = 10;

vm.loadData = function ()
{
    userService.GetAllRecords(page)
    .success(function (data)
    {
        allData = data;
        vm.loadMore(); // Set first 10 items
    })
    .error(function (error)
    {
        vm.status = 'Error retrieving data! ' + error.message;
    });
}

vm.loadMore = function () {
    // Add more items to the currentItems
    vm.currentItems = vm.currentItems.concat(allItems.slice(page*step, step));
    page++;
}

vm.loadData();

But it depends on what you are trying to achieve why you would want this. If most of the time the users only need to see the first 10 items, then I would recommend to do a http request each time you want to load more. If a user usually scrolls through all the items, then loading all data at once may be what you want.

Upvotes: 1

Joshua Kelly
Joshua Kelly

Reputation: 1063

I've used this module myself in a few applications and this is how you would restrict the call to only running once until your data has been returned.

js code

vm.isBusy = false;

vm.loadMore = function() {
    vm.isBusy = true;

    userService.GetAllRecords(page).success(function(data) {
        var results = data;

        for (var i = 0; i < results.length; i++) {
            vm.items.push(results[i]);
        }

        page++;
        vm.isBusy = false;
    });
}

template code

<div infinite-scroll="loadMore()" infinite-scroll-distance="0" infinite-scroll-disabled="isBusy"></div>

-

This is the code i wrote the last time i used this module.

<div infinite-scroll="loadMoreArticles()" infinite-scroll-distance="0" infinite-scroll-disabled="loadingArticles"></div>

$scope.loadingArticles = false;

$scope.loadMoreArticles = function() {
    $scope.loadingArticles = true;

    return articlesFactory.getArticles($stateParams.feedType || 'feed', $stateParams.feed, lastArticle.id).then(function(data) {
        $scope.articles = _.union($scope.articles, data);
        if (data.length > 0) {
            $scope.loadingArticles = false;
        }
    });
};

Upvotes: 0

Related Questions