Ответ 1
Используйте $timeout
вместо window.setTimeOut
. $timeout
правильно завербован, чтобы работать последовательно в Angular.
У меня уже есть разбиение на страницы. Теперь я хочу, чтобы разбиение на страницы было обновлено после фильтрации моих результатов.
Форма:
<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/
Используйте $timeout
вместо window.setTimeOut
. $timeout
правильно завербован, чтобы работать последовательно в Angular.
@abject_error ответ, используя $timeout
, работает. Я отредактировал вашу скрипку с его предложением и сделал это jsFiddle
CAVEAT
Я думаю, что это решение указывает на большую проблему в виде состояния гонки!
и эта скрипка - это путь вокруг него для реалов.
И вот объяснение
Ваше условие гонки заключается в обработке изменения 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>
Вместо этого вы можете просто использовать эту директиву:
https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination
Он предлагает разбиение на страницы с фильтром, сохраняя код приятным и чистым.
Престижность майклабромли за отличный код.
Используйте 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/