web-dev-qa-db-fra.com

Pagination sur une liste avec 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 uniquement 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 de sélection avec certaines valeurs afin de limiter le nombre d'éléments à afficher. Ce que je veux maintenant, c’est d’ajouter la pagination pour afficher les prochains 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 afin de 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}
        });
    });
130
Tomarto

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 moment donné.

Voici un exemple simple de pagination: http://jsfiddle.net/2ZzZB/56/

Cet exemple figurait sur la liste de violons du wiki angular.js github, ce qui devrait être utile: https://github.com/angular/angular.js/wiki/JsFiddle-Examples

EDIT: http://jsfiddle.net/2ZzZB/16/ à http://jsfiddle.net/2ZzZB/56/ (ne montrera pas "1/4.5 "s'il y a 45 résultats)

213
Andrew Joslin

Je viens de faire un JSFiddle qui montre la pagination + recherche + ordre sur chaque colonne en utilisant Construire avec Twitter Bootstrap code: http: // jsfiddle .net/SAWsA/11 /

39
Spir

J'ai construit un module qui simplifie incroyablement la pagination en mémoire.

Il vous permet de paginer simplement en remplaçant ng-repeat par dir-paginate, en spécifiant les éléments par page comme filtre de passe-passe, 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>

Aucun code de pagination spécial n'est nécessaire dans votre contrôleur. Tout est géré en interne par le module.

Démo: http://plnkr.co/edit/Wtkv71LIqUR4OhzhgpqL?p=preview

Source: dirPagination of GitHub

14
Michael Bromley

Je sais que ce fil est vieux maintenant mais je réponds pour que les choses restent un peu à jour.

Avec Angular 1.4 et les versions ultérieures, vous pouvez directement utiliser le filtre limitTo qui, outre l'acceptation du paramètre limit, accepte également le 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 une pagination. J'ai créé un violon pour illustrer la même chose.

5
Bharat Gupta

Découvrez cette directive: https://github.com/samu/angular-table

Il automatise beaucoup le tri et la pagination et vous laisse suffisamment de liberté pour personnaliser votre table/liste comme vous le souhaitez.

3
Samuel Müller

Voici un code de démonstration où il y a pagination + Filtering with 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>
2
Brahim LAMJAGUAR