Подтвердить что ты не робот

Обновление разбивки на страницы в AngularJS после фильтрации

У меня уже есть разбиение на страницы. Теперь я хочу, чтобы разбиение на страницы было обновлено после фильтрации моих результатов.

Форма:

<input type="text" data-ng-model="search.name" data-ng-change="filter()"/>

Список:

<li data-ng-repeat="data in filtered = (list | filter:search) | filter:search | startFrom:(currentPage-1)*entryLimit | limitTo:entryLimit">{{data.name}}</li>

Разбивка страницы:

<pagination data-boundary-links="true" data-num-pages="noOfPages" data-current-page="currentPage" max-size="maxSize"></pagination>

Контроллер:

$scope.filter = function() {
    window.setTimeout(function() { //wait for 'filtered' to be changed
        $scope.noOfPages = Math.ceil($scope.filtered.length/$scope.entryLimit);
        $scope.setPage = function(pageNo) {
            $scope.currentPage = pageNo;
        };
    }, 10);
};

Моя проблема в том, что разбиение на страницы просто обновляется после нажатия на номер страницы или после ввода следующего символа в поле ввода. Поэтому он обновляет один шаг до конца.

EDIT: я добавил источник в jsFiddle: http://jsfiddle.net/eqCWL/2/

4b9b3361

Ответ 1

Используйте $timeout вместо window.setTimeOut. $timeout правильно завербован, чтобы работать последовательно в Angular.

Ответ 2

@abject_error ответ, используя $timeout, работает. Я отредактировал вашу скрипку с его предложением и сделал это jsFiddle

CAVEAT

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

jsFiddle с использованием filterFilter и $watch

и эта скрипка - это путь вокруг него для реалов.

И вот объяснение

Ваше условие гонки заключается в обработке изменения search и доступности $scope.filtered.

Я думаю, что виновниками устранения этой проблемы являются:

ng-model="search" ng-change="filter()"

и

ng-repeat="data in filtered = (list | filter:search)......."

Используя ng-change, чтобы отключить "filter()", чтобы выполнить вычисление noOfPages, но также в зависимости от изменения в поиске, чтобы создать filtered. Выполняя это так, убедитесь, что отфильтрованный список не может быть готов вовремя для вычисления количества страниц, а также из-за того, что косоглазие "filter()" на 10 мс с тайм-аутом дает иллюзию рабочей программы.

Что вам нужно, это способ "смотреть" search для изменений, а затем фильтровать список в том месте, где у вас есть доступ к созданию $scope.filtered и вычислению $scope.noOfPages. Все в последовательности, без гонки.

Angular имеет такой путь! В вашем контроллере можно использовать фильтр filter, поскольку функция очень плохо названа: filterFilter. Проверьте это в Руководстве по фильтрам - Использование фильтров в контроллерах и службах

Внесите его в контроллер.

function pageCtrl($scope, filterFilter) {
    // ...
}

Используйте его в функции $watch, задокументированной в

и

<li ng-repeat="data in filtered | startFrom:(currentPage-1)*entryLimit | limitTo:entryLimit">
    {{data.name}}
</li>

Ответ 3

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

https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination

Он предлагает разбиение на страницы с фильтром, сохраняя код приятным и чистым.

Престижность майклабромли за отличный код.

Ответ 4

Используйте angular $scope.$watch

$scope.$watch('search', function(term) {
    $scope.filter = function() {
        $scope.noOfPages = Math.ceil($scope.filtered.length/$scope.entryLimit);
    }
});

Источник; http://jsfiddle.net/eqCWL/2/

Демо; http://jsfiddle.net/eqCWL/192/