paginador paginacion con bootstrap angularjs pagination

paginacion - ¿Cómo hacer la paginación en AngularJS?



pagination angular 5 (21)

Tengo un conjunto de datos de aproximadamente 1000 elementos en memoria y estoy intentando crear un buscapersonas para este conjunto de datos, pero no estoy seguro de cómo hacerlo.

Estoy usando una función de filtro personalizado para filtrar los resultados, y eso funciona bien, pero de alguna manera necesito sacar el número de páginas.

¿Alguna pista?


Resumen : Paginación utilizando

- ng-repeat - uib-pagination

Ver :

<div class="row"> <div class="col-lg-12"> <table class="table"> <thead style="background-color: #eee"> <tr> <td>Dispature</td> <td>Service</td> <td>Host</td> <td>Value</td> </tr> </thead> <tbody> <tr ng-repeat="x in app.metricsList"> <td>{{x.dispature}}</td> <td>{{x.service}}</td> <td>{{x.host}}</td> <td>{{x.value}}</td> </tr> </tbody> </table> <div align="center"> <uib-pagination items-per-page="app.itemPerPage" num-pages="numPages" total-items="app.totalItems" boundary-link-numbers="true" ng-model="app.currentPage" rotate="false" max-size="app.maxSize" class="pagination-sm" boundary-links="true" ng-click="app.getPagableRecords()"></uib-pagination> <div style="float: right; margin: 15px"> <pre>Page: {{app.currentPage}} / {{numPages}}</pre> </div> </div> </div> </div>

Controlador JS :

app.controller(''AllEntryCtrl'',[''$scope'',''$http'',''$timeout'',''$rootScope'', function($scope,$http,$timeout,$rootScope){ var app = this; app.currentPage = 1; app.maxSize = 5; app.itemPerPage = 5; app.totalItems = 0; app.countRecords = function() { $http.get("countRecord") .success(function(data,status,headers,config){ app.totalItems = data; }) .error(function(data,status,header,config){ console.log(data); }); }; app.getPagableRecords = function() { var param = { page : app.currentPage, size : app.itemPerPage }; $http.get("allRecordPagination",{params : param}) .success(function(data,status,headers,config){ app.metricsList = data.content; }) .error(function(data,status,header,config){ console.log(data); }); }; app.countRecords(); app.getPagableRecords(); }]);


Pistola de seguridad de interfaz de usuario angular - Directiva de paginación

Echa un vistazo a la directiva de paginación de UI Bootstrap . Terminé usándolo en lugar de lo que se publica aquí, ya que tiene suficientes funciones para mi uso actual y tiene una especificación de prueba exhaustiva para acompañarlo.

Ver

<!-- table here --> <pagination ng-model="currentPage" total-items="todos.length" max-size="maxSize" boundary-links="true"> </pagination> <!-- items/page select here if you like -->

Controlador

todos.controller("TodoController", function($scope) { $scope.filteredTodos = [] ,$scope.currentPage = 1 ,$scope.numPerPage = 10 ,$scope.maxSize = 5; $scope.makeTodos = function() { $scope.todos = []; for (i=1;i<=1000;i++) { $scope.todos.push({ text:"todo "+i, done:false}); } }; $scope.makeTodos(); $scope.$watch("currentPage + numPerPage", function() { var begin = (($scope.currentPage - 1) * $scope.numPerPage) , end = begin + $scope.numPerPage; $scope.filteredTodos = $scope.todos.slice(begin, end); }); });

He hecho un plunker de trabajo para referencia.

Versión heredada:

Ver

<!-- table here --> <div data-pagination="" data-num-pages="numPages()" data-current-page="currentPage" data-max-size="maxSize" data-boundary-links="true"></div> <!-- items/page select here if you like -->

Controlador

todos.controller("TodoController", function($scope) { $scope.filteredTodos = [] ,$scope.currentPage = 1 ,$scope.numPerPage = 10 ,$scope.maxSize = 5; $scope.makeTodos = function() { $scope.todos = []; for (i=1;i<=1000;i++) { $scope.todos.push({ text:"todo "+i, done:false}); } }; $scope.makeTodos(); $scope.numPages = function () { return Math.ceil($scope.todos.length / $scope.numPerPage); }; $scope.$watch("currentPage + numPerPage", function() { var begin = (($scope.currentPage - 1) * $scope.numPerPage) , end = begin + $scope.numPerPage; $scope.filteredTodos = $scope.todos.slice(begin, end); }); });

He hecho un plunker de trabajo para referencia.


Acabo de hacer un JSFiddle que muestra el orden de paginación + búsqueda + en cada columna usando el código btford: http://jsfiddle.net/SAWsA/11/


Ahí está mi ejemplo. Botón seleccionado en el centro de la lista Controlador. config >>>

$scope.pagination = {total: null, pages: [], config: {count: 10, page: 1, size: 7}};

Lógica para la paginación:

/* Pagination */ $scope.$watch(''pagination.total'', function (total) { if(!total || total <= $scope.pagination.config.count) return; _setPaginationPages(total); }); function _setPaginationPages(total) { var totalPages = Math.ceil(total / $scope.pagination.config.count); var pages = []; var start = $scope.pagination.config.page - Math.floor($scope.pagination.config.size/2); var finish = null; if((start + $scope.pagination.config.size - 1) > totalPages){ start = totalPages - $scope.pagination.config.size; } if(start <= 0) { start = 1; } finish = start + $scope.pagination.config.size - 1; if(finish > totalPages){ finish = totalPages; } for (var i = start; i <= finish; i++) { pages.push(i); } $scope.pagination.pages = pages; } $scope.$watch("pagination.config.page", function(page){ _setPaginationPages($scope.pagination.total); _getRespondents($scope.pagination.config); });

y mi punto de vista en el arranque

<ul ng-class="{hidden: pagination.total == 0}" class="pagination"> <li ng-click="pagination.config.page = pagination.config.page - 1" ng-class="{disabled: pagination.config.page == 1}" ><a href="#">&laquo;</a></li> <li ng-repeat="p in pagination.pages" ng-click="pagination.config.page = p" ng-class="{active: p == pagination.config.page}"><a href="#">{{p}}</a></li> <li ng-click="pagination.config.page = pagination.config.page + 1" ng-class="{disabled: pagination.config.page == pagination.pages.length}"><a href="#">&raquo;</a></li> </ul >

Es útil


Debajo de la solución es bastante simple.

<pagination total-items="totalItems" items-per-page= "itemsPerPage" ng-model="currentPage" class="pagination-sm"> </pagination> <tr ng-repeat="country in countries.slice((currentPage -1) * itemsPerPage, currentPage * itemsPerPage) ">

Aquí está la muestra de jsfiddle.


Desde Angular 1.4, el filtro limitTo también acepta un segundo argumento opcional.

De la docs :

{{limitTo_expression | limitTo: limit: begin}}

comenzar (opcional) cadena | número
Índice en el que comenzar la limitación. Como índice negativo, el inicio indica un desplazamiento desde el final de la entrada. El valor predeterminado es 0.

Por lo tanto, no es necesario crear una nueva directiva . Este argumento se puede usar para establecer el desplazamiento de la paginación

ng-repeat="item in vm.items| limitTo: vm.itemsPerPage: (vm.currentPage-1)*vm.itemsPerPage"



Esta es una solución javascript pura que he envuelto como un servicio Angular para implementar la lógica de paginación como en los resultados de búsqueda de Google.

Demostración de trabajo en CodePen en http://codepen.io/cornflourblue/pen/KVeaQL/

Detalles y explicaciones en este blog.

function PagerService() { // service definition var service = {}; service.GetPager = GetPager; return service; // service implementation function GetPager(totalItems, currentPage, pageSize) { // default to first page currentPage = currentPage || 1; // default page size is 10 pageSize = pageSize || 10; // calculate total pages var totalPages = Math.ceil(totalItems / pageSize); var startPage, endPage; if (totalPages <= 10) { // less than 10 total pages so show all startPage = 1; endPage = totalPages; } else { // more than 10 total pages so calculate start and end pages if (currentPage <= 6) { startPage = 1; endPage = 10; } else if (currentPage + 4 >= totalPages) { startPage = totalPages - 9; endPage = totalPages; } else { startPage = currentPage - 5; endPage = currentPage + 4; } } // calculate start and end item indexes var startIndex = (currentPage - 1) * pageSize; var endIndex = startIndex + pageSize; // create an array of pages to ng-repeat in the pager control var pages = _.range(startPage, endPage + 1); // return object with all pager properties required by the view return { totalItems: totalItems, currentPage: currentPage, pageSize: pageSize, totalPages: totalPages, startPage: startPage, endPage: endPage, startIndex: startIndex, endIndex: endIndex, pages: pages }; } }


He extraído los bits relevantes aquí. Este es un buscapersonas tabular ''sin adornos'', por lo que no se incluye la clasificación o el filtrado. Siéntase libre de cambiar / agregar según sea necesario:

//your data source may be different. the following line is //just for demonstration purposes only var modelData = [{ text: ''Test1'' }, { text: ''Test2'' }, { text: ''Test3'' }]; (function(util) { util.PAGE_SIZE = 10; util.range = function(start, end) { var rng = []; if (!end) { end = start; start = 0; } for (var i = start; i < end; i++) rng.push(i); return rng; }; util.Pager = function(data) { var self = this, _size = util.PAGE_SIZE;; self.current = 0; self.content = function(index) { var start = index * self.size, end = (index * self.size + self.size) > data.length ? data.length : (index * self.size + self.size); return data.slice(start, end); }; self.next = function() { if (!self.canPage(''Next'')) return; self.current++; }; self.prev = function() { if (!self.canPage(''Prev'')) return; self.current--; }; self.canPage = function(dir) { if (dir === ''Next'') return self.current < self.count - 1; if (dir === ''Prev'') return self.current > 0; return false; }; self.list = function() { var start, end; start = self.current < 5 ? 0 : self.current - 5; end = self.count - self.current < 5 ? self.count : self.current + 5; return Util.range(start, end); }; Object.defineProperty(self, ''size'', { configurable: false, enumerable: false, get: function() { return _size; }, set: function(val) { _size = val || _size; } }); Object.defineProperty(self, ''count'', { configurable: false, enumerable: false, get: function() { return Math.ceil(data.length / self.size); } }); }; })(window.Util = window.Util || {}); (function(ns) { ns.SampleController = function($scope, $window) { $scope.ModelData = modelData; //instantiate pager with array (i.e. our model) $scope.pages = new $window.Util.Pager($scope.ModelData); }; })(window.Controllers = window.Controllers || {});

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <table ng-controller="Controllers.SampleController"> <thead> <tr> <th> Col1 </th> </tr> </thead> <tbody> <tr ng-repeat="item in pages.content(pages.current)" title="{{item.text}}"> <td ng-bind-template="{{item.text}}"></td> </tr> </tbody> <tfoot> <tr> <td colspan="4"> <a href="#" ng-click="pages.prev()">&laquo;</a> <a href="#" ng-repeat="n in pages.list()" ng-click="pages.current = n" style="margin: 0 2px;">{{n + 1}}</a> <a href="#" ng-click="pages.next()">&raquo;</a> </td> </tr> </tfoot> </table>


He tenido que implementar la paginación varias veces con Angular, y siempre fue un poco molesto por algo que sentí que podía simplificarse. He utilizado algunas de las ideas presentadas aquí y en otros lugares para crear un módulo de paginación que hace que la paginación sea tan simple como:

<ul> <li dir-paginate="item in items | itemsPerPage: 10">{{ item }}</li> </ul> // then somewhere else on the page .... <dir-pagination-controls></dir-pagination-controls>

Eso es. Tiene las siguientes características:

  • No se necesita un código personalizado en su controlador para vincular los items la colección a los enlaces de paginación.
  • No está obligado a usar una tabla o vista de cuadrícula, ¡puede paginar cualquier cosa que pueda repetir!
  • Delegados en ng-repeat , por lo que puede utilizar cualquier expresión que se pueda usar válidamente en una ng-repeat , incluido el filtrado, el orden, etc.
  • Funciona en todos los controladores: la directiva pagination-controls no necesita saber nada sobre el contexto en el que se llama la directiva pagination-controls .

Demostración: http://plnkr.co/edit/Wtkv71LIqUR4OhzhgpqL?p=preview

Para aquellos que buscan una solución "plug and play", creo que encontrará esto útil.

Código

El código está disponible aquí en GitHub e incluye un buen conjunto de pruebas:

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

Si está interesado, también escribí una breve pieza con un poco más de información sobre el diseño del módulo: http://www.michaelbromley.co.uk/blog/108/paginate-almost-anything-in-angularjs/


Los mensajes anteriores recomendaban básicamente cómo construir una paginación por ti mismo. Si usted es como yo y prefiere una directiva terminada, acabo de encontrar una excelente llamada ngTable . Es compatible con la clasificación, el filtrado y la paginación.

Es una solución muy limpia, todo lo que necesita en su opinión:

<table ng-table="tableParams" class="table"> <tr ng-repeat="user in $data"> <td data-title="''Name''" sortable="''name''"> {{user.name}} </td> <td data-title="''Age''" sortable="''age''"> {{user.age}} </td> </tr> </table>

Y en el controlador:

$scope.tableParams = new ngTableParams({ page: 1, // show first page count: 10, // count per page sorting: { name: ''asc'' // initial sorting } }, { total: data.length, // length of data getData: function($defer, params) { // use build-in angular filter var orderedData = params.sorting() ? $filter(''orderBy'')(data, params.orderBy()) : data; var start = (params.page() - 1) * params.count(); var end = params.page() * params.count(); $defer.resolve(orderedData.slice( start, end)); } });

Enlace a GitHub: https://github.com/esvit/ng-table/


Me gustaría agregar mi solución que funcione con ngRepeat y los filtros que usa con ella sin usar un $watch o una matriz segmentada.

¡Sus resultados de filtro serán paginados!

var app = angular.module(''app'', [''ui.bootstrap'']); app.controller(''myController'', [''$scope'', function($scope){ $scope.list= [''a'', ''b'', ''c'', ''d'', ''e'']; $scope.pagination = { currentPage: 1, numPerPage: 5, totalItems: 0 }; $scope.searchFilter = function(item) { //Your filter results will be paginated! //The pagination will work even with other filters involved //The total number of items in the result of your filter is accounted for }; $scope.paginationFilter = function(item, index) { //Every time the filter is used it restarts the totalItems if(index === 0) $scope.pagination.totalItems = 0; //This holds the totalItems after the filters are applied $scope.pagination.totalItems++; if( index >= (($scope.pagination.currentPage - 1) * $scope.pagination.numPerPage) && index < ((($scope.pagination.currentPage - 1) * $scope.pagination.numPerPage) + $scope.pagination.numPerPage) ) return true; //return true if item index is on the currentPage return false; }; }]);

En el HTML, asegúrese de aplicar sus filtros al ngRepeat antes del filtro de paginación.

<table data-ng-controller="myController"> <tr data-ng-repeat="item in list | filter: searchFilter | filter: paginationFilter track by $index"> <td> {{item}} </td> <tr> </table> <ul class="pagination-sm" uib-pagination data-boundary-links="true" data-total-items="pagination.totalItems" data-items-per-page="pagination.numPerPage" data-ng-model="pagination.currentPage" data-previous-text="&lsaquo;" data-next-text="&rsaquo;" data-first-text="&laquo;" data-last-text="&raquo;"> </ul>


Me gustaría poder comentar, pero tendré que dejar esto aquí:

La respuesta de Scotty.NET y el rehacer de user2176745 para versiones posteriores son geniales, pero ambos extrañan algo en lo que mi versión de AngularJS (v1.3.15) rompe en:

i no está definido en $ scope.makeTodos.

Como tal, el reemplazo con esta función lo corrige para versiones angulares más recientes.

$scope.makeTodos = function() { var i; $scope.todos = []; for (i=1;i<=1000;i++) { $scope.todos.push({ text:''todo ''+i, done:false}); } };


Para cualquiera que tenga dificultades como yo para crear un paginador para una tabla, publico esto. Por lo tanto, en su opinión:

<pagination total-items="total" items-per-page="itemPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination> <!-- To specify your choice of items Per Pages--> <div class="btn-group"> <label class="btn btn-primary" ng-model="radioModel" btn-radio="''Left''" data-ng-click="setItems(5)">5</label> <label class="btn btn-primary" ng-model="radioModel" btn-radio="''Middle''" data-ng-click="setItems(10)">10</label> <label class="btn btn-primary" ng-model="radioModel" btn-radio="''Right''" data-ng-click="setItems(15)">15</label> </div> //And don''t forget in your table: <tr data-ng-repeat="p in profiles | offset: (currentPage-1)*itemPerPage | limitTo: itemPerPage" >

En su angularJs:

var module = angular.module(''myapp'',[''ui.bootstrap'',''dialogs'']); module.controller(''myController'',function($scope,$http){ $scope.total = $scope.mylist.length; $scope.currentPage = 1; $scope.itemPerPage = 2; $scope.start = 0; $scope.setItems = function(n){ $scope.itemPerPage = n; }; // In case you can replace ($scope.currentPage - 1) * $scope.itemPerPage in <tr> by "start" $scope.pageChanged = function() { $scope.start = ($scope.currentPage - 1) * $scope.itemPerPage; }; }); //and our filter module.filter(''offset'', function() { return function(input, start) { start = parseInt(start, 10); return input.slice(start); }; });


Pregunta antigua, pero como creo que mi enfoque es un poco diferente y menos complejo, compartiré esto y espero que alguien además de mí lo encuentre útil.

Lo que encontré como una solución fácil y pequeña para la paginación es combinar una directiva con un filtro que usa las mismas variables de alcance.

Para implementar esto, agregue el filtro en la matriz y agregue el directiv como este

<div class="row"> <table class="table table-hover"> <thead> <tr> <th>Name</th> <th>Price</th> <th>Quantity</th> </tr> </thead> <tbody> <tr ng-repeat="item in items | cust_pagination:p_Size:p_Step"> <td>{{item.Name}}</td> <td>{{item.Price}}</td> <td>{{item.Quantity}}</td> </tr> </tbody> </table> <div cust-pagination p-items="items" p-boundarylinks="true" p-size="p_Size" p-step="p_Step"></div> </div>

p_Size y p_Step son variables de alcance que pueden personalizarse en el ámbito; de lo contrario, el valor predeterminado de p_Size es 5 y p_Step es 1.

Cuando se cambia un paso en la paginación, se actualiza p_Step y se activará un nuevo filtro mediante el filtro cust_pagination. El filtro cust_pagination luego corta la matriz según el valor de p_Step como se muestra a continuación y solo devuelve los registros activos seleccionados en la sección de paginación

var startIndex = nStep * nPageSize; var endIndex = startIndex + nPageSize; var arr = items.slice(startIndex, endIndex); return arr;

DEMO Ver la solución completa en este plunker


Puede hacerlo fácilmente utilizando la directiva de la interfaz de usuario de Bootstrap.

Esta respuesta es una modificación de la respuesta dada por @ Scotty.NET. He cambiado el código porque la directiva <pagination> ahora está en desuso.

El siguiente código genera la paginación:

<ul uib-pagination boundary-links="true" total-items="totalItems" items-per-page="itemsPerPage" ng-model="currentPage" ng-change="pageChanged()" class="pagination" previous-text="&lsaquo;" next-text="&rsaquo;" first-text="&laquo;" last-text="&raquo;"></ul>

Para hacerlo funcional, usa esto en tu controlador:

$scope.filteredData = [] $scope.totalItems = $scope.data.length; $scope.currentPage = 1; $scope.itemsPerPage = 5; $scope.setPage = function (pageNo) { $scope.currentPage = pageNo; }; $scope.pageChanged = function() { var begin = (($scope.currentPage - 1) * $scope.itemsPerPage) , end = begin + $scope.itemsPerPage; $scope.filteredData = $scope.data.slice(begin, end); }; $scope.pageChanged();

Consulte esto para obtener más opciones de paginación: Directiva de paginación de la interfaz de usuario de Bootstrap


Recientemente implementé la paginación para el sitio Construido con Angular. Puede verificar la fuente: https://github.com/angular/builtwith.angularjs.org

Evitaría usar un filtro para separar las páginas. Debe dividir los elementos en páginas dentro del controlador.



plunkr http://plnkr.co/edit/FUeWwDu0XzO51lyLAEIA?p=preview Scotty.NET para que use versiones más nuevas de angular, angular-ui y bootstrap.

Controlador

var todos = angular.module(''todos'', [''ui.bootstrap'']); todos.controller(''TodoController'', function($scope) { $scope.filteredTodos = []; $scope.itemsPerPage = 30; $scope.currentPage = 4; $scope.makeTodos = function() { $scope.todos = []; for (i=1;i<=1000;i++) { $scope.todos.push({ text:''todo ''+i, done:false}); } }; $scope.figureOutTodosToDisplay = function() { var begin = (($scope.currentPage - 1) * $scope.itemsPerPage); var end = begin + $scope.itemsPerPage; $scope.filteredTodos = $scope.todos.slice(begin, end); }; $scope.makeTodos(); $scope.figureOutTodosToDisplay(); $scope.pageChanged = function() { $scope.figureOutTodosToDisplay(); }; });

Componente UI Bootstrap

<pagination boundary-links="true" max-size="3" items-per-page="itemsPerPage" total-items="todos.length" ng-model="currentPage" ng-change="pageChanged()"></pagination>


Angular-Paging

es una maravillosa elección

Una directiva para ayudar en la paginación de grandes conjuntos de datos mientras se requiere el mínimo de información de paginación real. Somos muy dependientes del servidor para "filtrar" los resultados en este esquema de paginación. La idea central es que solo queremos mantener la "página" activa de elementos, en lugar de mantener la lista completa de elementos en memoria y paginación en el lado del cliente.


ng-repetir paginación

<div ng-app="myApp" ng-controller="MyCtrl"> <input ng-model="q" id="search" class="form-control" placeholder="Filter text"> <select ng-model="pageSize" id="pageSize" class="form-control"> <option value="5">5</option> <option value="10">10</option> <option value="15">15</option> <option value="20">20</option> </select> <ul> <li ng-repeat="item in data | filter:q | startFrom:currentPage*pageSize | limitTo:pageSize"> {{item}} </li> </ul> <button ng-disabled="currentPage == 0" ng-click="currentPage=currentPage-1"> Previous </button> {{currentPage+1}}/{{numberOfPages()}} <button ng-disabled="currentPage >= getData().length/pageSize - 1" ng- click="currentPage=currentPage+1"> Next </button> </div> <script> var app=angular.module(''myApp'', []); app.controller(''MyCtrl'', [''$scope'', ''$filter'', function ($scope, $filter) { $scope.currentPage = 0; $scope.pageSize = 10; $scope.data = []; $scope.q = ''''; $scope.getData = function () { return $filter(''filter'')($scope.data, $scope.q) } $scope.numberOfPages=function(){ return Math.ceil($scope.getData().length/$scope.pageSize); } for (var i=0; i<65; i++) { $scope.data.push("Item "+i); } }]); app.filter(''startFrom'', function() { return function(input, start) { start = +start; //parse to int return input.slice(start); } }); </script>