Angular JS ngInfiniteScroll с LimitTo

Я использую ngInfiniteScroll ng-модуль для разбиения на страницы. Когда я прокручиваю страницу вниз, я добавляю 20 записей в свою таблицу данных. Делая это, я каждый раз запускаю http-запрос («не очень хорошо для производительности»).

Я провел некоторое исследование и наткнулся на добавление LimitTo с помощью ngInfiniteScroll. Не уверен, как это реализовать. Может кто-нибудь, пожалуйста, дайте мне какие-либо предложения.

   <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>

/**** КОНТРОЛЛЕР.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;
        });
    }

person Erkan Demir    schedule 29.05.2015    source источник
comment
Если вы не хотите каждый раз загружать новые данные, то зачем использовать бесконечную прокрутку? Какова ваша цель?   -  person devqon    schedule 29.05.2015
comment
Я хочу каждый раз загружать новые данные. Однако мне было интересно, есть ли альтернативный способ загрузки данных вместо вызова http-запроса каждый раз, когда я прокручиваю. например загрузить все данные один раз при использовании фильтра limitTo для добавления данных   -  person Erkan Demir    schedule 29.05.2015
comment
Да, вы можете загружать все данные сразу и добавлять фрагменты во время прокрутки. Но я действительно думаю, что HTTP-запрос — это то, что вам нужно с бесконечной прокруткой.   -  person devqon    schedule 29.05.2015
comment
Не мог бы я просто вызвать http-запрос один раз и загрузить все данные в массив. затем используйте фильтр limitTo, чтобы добавить, например. + 20 записей каждый раз, когда я прокручиваю?   -  person Erkan Demir    schedule 29.05.2015


Ответы (2)


Вы можете загрузить все данные один раз и добавлять фрагменты при прокрутке:

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();

Но это зависит от того, чего вы пытаетесь достичь, почему вам это нужно. Если в большинстве случаев пользователям нужно видеть только первые 10 элементов, я бы рекомендовал делать http-запрос каждый раз, когда вы хотите загрузить больше. Если пользователь обычно прокручивает все элементы, то загрузка всех данных сразу может быть тем, что вам нужно.

person devqon    schedule 29.05.2015
comment
Причина, по которой я хочу сделать http-запрос один раз, связана с тем, что у меня есть поисковый фильтр, и вы можете фильтровать только по доступным записям, отображающим не весь список данных. @devqon - person Erkan Demir; 30.06.2015
comment
Да, тогда вы вполне можете это сделать, но если у вас есть тысячи записей, это не будет хорошей идеей. Вы всегда можете выполнять фильтрацию на стороне сервера с помощью поиска - person devqon; 30.06.2015
comment
Я, вероятно, закончу тем, что у меня будет миллион записей. Что было бы лучшим решением? @devqon - person Erkan Demir; 01.07.2015

Я сам использовал этот модуль в нескольких приложениях, и именно так вы можете ограничить вызов только один раз, пока ваши данные не будут возвращены.

js-код

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;
    });
}

код шаблона

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

-

Это код, который я написал в последний раз, когда использовал этот модуль.

<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;
        }
    });
};
person Joshua Kelly    schedule 29.05.2015
comment
Привет, Джошуа, в чем разница между твоим постом и моим исходным кодом? - person Erkan Demir; 29.05.2015
comment
tF.loadMore() / tF.isBusy. Не видя остальной части вашего кода, tF не имеет ссылки. - person Joshua Kelly; 29.05.2015
comment
tF — мое соглашение об именах. Я использую ControllerAS: в моем состоянии пользовательского интерфейса - person Erkan Demir; 29.05.2015