Pagination: pageChanged handler should accept `newPageSize` when working with Asynchronous Data
When working with Asynchronous Data, a change in pageSize should re-trigger an async call as well (and possibly do some recalculation):
$scope.pageChanged = function(newPage, newPageSize) {
getResultsPage(newPage, newPageSize);
};
<dir-pagination-controls on-page-change="pageChanged(newPageNumber, newPageSize)"></dir-pagination-controls>
- Implementation example: How UI Grid handles pagination: http://ui-grid.info/docs/#/api/ui.grid.pagination.api:PublicAPI#events_paginationchanged
- Dependant on: https://github.com/michaelbromley/angularUtils/issues/211
Looking at uigrid's code I found a clue for the way the watcher is written:
https://github.com/angular-ui/ui-grid/blob/7420b4b54eba5798053b99d1c6c0dcc67c530080/src/features/pagination/js/pagination.js#L377
Ok this is how I implemented this on application level, aklthoug it would be nice to be incorporated into the directive:
View:
<div class="panel-footer clearfix">
<div class="pull-left">
<select
ng-model="vm.options.paginationPageSize"
ng-options="o as o for o in vm.options.paginationPageSizes">
</select>
records per page
</div>
<dir-pagination-controls
boundary-links="true"
template-url="directives/shared/dirPagination.tpl.html">
</dir-pagination-controls>
</div>
Controller:
var vm = this;
// Default options
vm.options = {};
vm.options.paginationPageSizes = [4, 8, 16, 32, 64, 128];
vm.options.totalItems = 100;
vm.options.paginationPageSize = 10;
vm.options.currentPage = 1;
// Instead of using on-page-change attribute, implement this watcher:
$scope.$watch('vm.options.currentPage + vm.options.paginationPageSize', (newValues, oldValues) => {
if (newValues === oldValues) {
return;
}
vm.makeAjaxCall(vm.options.currentPage, vm.options.paginationPageSize)
});
Updated to avoid infinite loops in some scenarios:
var vm = this;
// Default options
vm.options = {};
vm.options.paginationPageSizes = [4, 8, 16, 32, 64, 128];
vm.options.totalItems = 100;
vm.options.paginationPageSize = 10;
vm.options.currentPage = 1;
vm.getTotalPages = function() {
if (!vm.catalog.totalItems) { // (!vm.options.enablePagination) {
return null;
}
return (vm.options.totalItems === 0) ? 1 : Math.ceil(vm.options.totalItems / vm.options.paginationPageSize);
};
// Instead of using on-page-change attribute, implement this watcher:
$scope.$watch('vm.options.currentPage + vm.options.paginationPageSize', (newValues, oldValues) => {
if (newValues === oldValues || oldValues === undefined) {
return;
}
if (!angular.isNumber(vm.options.currentPage) || vm.options.currentPage < 1) {
vm.options.currentPage = 1;
return;
}
if (vm.options.totalItems > 0 && vm.options.currentPage > vm.getTotalPages()) {
vm.options.currentPage = vm.getTotalPages();
return;
}
vm.paginationChangeHandler({
newPage: vm.options.currentPage,
newPageSize: vm.options.paginationPageSize
});
});
Actually full credit goes to @brianchance who implemented this feature in ui-grid back in Nov 2014.