Pagination sur une liste en utilisant ng-repeat
J'essaie d'ajouter des pages à ma liste. J'ai suivi le tutoriel AngularJS, celui sur les smartphones et j'essaie d'afficher seulement un certain nombre d'objets. Voici mon fichier html:
<div class='container-fluid'>
<div class='row-fluid'>
<div class='span2'>
Search: <input ng-model='searchBar'>
Sort by:
<select ng-model='orderProp'>
<option value='name'>Alphabetical</option>
<option value='age'>Newest</option>
</select>
You selected the phones to be ordered by: {{orderProp}}
</div>
<div class='span10'>
<select ng-model='limit'>
<option value='5'>Show 5 per page</option>
<option value='10'>Show 10 per page</option>
<option value='15'>Show 15 per page</option>
<option value='20'>Show 20 per page</option>
</select>
<ul class='phones'>
<li class='thumbnail' ng-repeat='phone in phones | filter:searchBar | orderBy:orderProp | limitTo:limit'>
<a href='#/phones/{{phone.id}}' class='thumb'><img ng-src='{{phone.imageUrl}}'></a>
<a href='#/phones/{{phone.id}}'>{{phone.name}}</a>
<p>{{phone.snippet}}</p>
</li>
</ul>
</div>
</div>
</div>
J'ai ajouté une balise select avec certaines valeurs afin de limiter le nombre d'éléments qui seront affichés. Ce que je veux maintenant, c'est d'ajouter la pagination pour afficher les 5, 10, etc.
J'ai un contrôleur qui fonctionne avec ceci:
function PhoneListCtrl($scope, Phone){
$scope.phones = Phone.query();
$scope.orderProp = 'age';
$scope.limit = 5;
}
Et aussi j'ai un module pour récupérer les données des fichiers json.
angular.module('phonecatServices', ['ngResource']).
factory('Phone', function($resource){
return $resource('phones/:phoneId.json', {}, {
query: {method: 'GET', params:{phoneId:'phones'}, isArray:true}
});
});
6 réponses
Si vous n'avez pas trop de données, vous pouvez certainement faire de la pagination en stockant simplement toutes les données dans le navigateur et en filtrant ce qui est visible à un certain moment.
Voici un exemple simple de pagination: http://jsfiddle.net/2ZzZB/56/
Cet exemple était sur la liste des violons sur l'angulaire.js GitHub wiki, qui devrait être utile: https://github.com/angular/angular.js/wiki/JsFiddle-Examples
Modifier: http://jsfiddle.net/2ZzZB/16/ de http://jsfiddle.net/2ZzZB/56/ (n'affichera pas "1/4.5" s'il y a 45 résultats)
Je viens de faire un JSFiddle qui montre pagination + search + order by sur chaque colonne en utilisant Construire avec Twitter Bootstrap code: http://jsfiddle.net/SAWsA/11/
J'ai construit un module qui rend la pagination en mémoire incroyablement simple.
Il vous permet de paginer en remplaçant simplement ng-repeat
par dir-paginate
, en spécifiant les éléments par page comme filtre canalisé, puis en supprimant les contrôles où vous le souhaitez sous la forme d'une seule directive, <dir-pagination-controls>
Pour prendre L'exemple original demandé par Tomarto, cela ressemblerait à ceci:
<ul class='phones'>
<li class='thumbnail' dir-paginate='phone in phones | filter:searchBar | orderBy:orderProp | limitTo:limit | itemsPerPage: limit'>
<a href='#/phones/{{phone.id}}' class='thumb'><img ng-src='{{phone.imageUrl}}'></a>
<a href='#/phones/{{phone.id}}'>{{phone.name}}</a>
<p>{{phone.snippet}}</p>
</li>
</ul>
<dir-pagination-controls></dir-pagination-controls>
Il n'y a pas besoin de code de pagination spécial dans votre contrôleur. Tout est géré en interne par le module.
Démo: http://plnkr.co/edit/Wtkv71LIqUR4OhzhgpqL?p=preview
Source: dirPagination de GitHub
Je sais que ce fil est vieux maintenant mais je réponds pour garder les choses un peu à jour.
Avec Angular 1.4 et supérieur, vous pouvez directement utiliser limitTo filter qui, en plus d'accepter le paramètre limit
, accepte également un paramètre begin
.
Utilisation: {{ limitTo_expression | limitTo : limit : begin}}
Alors maintenant, vous n'avez peut-être pas besoin d'utiliser une bibliothèque tierce pour réaliser quelque chose comme la pagination. J'ai créé un violon pour illustrer le même.
Découvrez la présente directive: https://github.com/samu/angular-table
Il automatise beaucoup le tri et la pagination et vous donne assez de liberté pour personnaliser votre table/liste comme vous le souhaitez.
Voici un code de démonstration où il y a pagination + filtrage avec AngularJS:
Https://codepen.io/lamjaguar/pen/yOrVym
JS :
var app=angular.module('myApp', []);
// alternate - https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination
// alternate - http://fdietz.github.io/recipes-with-angular-js/common-user-interface-patterns/paginating-through-client-side-data.html
app.controller('MyCtrl', ['$scope', '$filter', function ($scope, $filter) {
$scope.currentPage = 0;
$scope.pageSize = 10;
$scope.data = [];
$scope.q = '';
$scope.getData = function () {
// needed for the pagination calc
// https://docs.angularjs.org/api/ng/filter/filter
return $filter('filter')($scope.data, $scope.q)
/*
// manual filter
// if u used this, remove the filter from html, remove above line and replace data with getData()
var arr = [];
if($scope.q == '') {
arr = $scope.data;
} else {
for(var ea in $scope.data) {
if($scope.data[ea].indexOf($scope.q) > -1) {
arr.push( $scope.data[ea] );
}
}
}
return arr;
*/
}
$scope.numberOfPages=function(){
return Math.ceil($scope.getData().length/$scope.pageSize);
}
for (var i=0; i<65; i++) {
$scope.data.push("Item "+i);
}
// A watch to bring us back to the
// first pagination after each
// filtering
$scope.$watch('q', function(newValue,oldValue){ if(oldValue!=newValue){
$scope.currentPage = 0;
}
},true);
}]);
//We already have a limitTo filter built-in to angular,
//let's make a startFrom filter
app.filter('startFrom', function() {
return function(input, start) {
start = +start; //parse to int
return input.slice(start);
}
});
HTML:
<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>