Comment faire de la pagination dans AngularJS?

254

J'ai un ensemble de données d'environ 1000 éléments en mémoire et j'essaie de créer un pageur pour cet ensemble de données, mais je ne sais pas comment procéder.

J'utilise une fonction de filtre personnalisée pour filtrer les résultats, et cela fonctionne très bien, mais je dois en quelque sorte obtenir le nombre de pages.

Des indices?

Micael
la source

Réponses:

285

Angular UI Bootstrap - Directive de pagination

Consultez l' interface utilisateur Bootstrap de directive de pagination . J'ai fini par l'utiliser plutôt que par ce qui est affiché ici car il a suffisamment de fonctionnalités pour mon utilisation actuelle et a une spécification de test approfondie pour l'accompagner.

Vue

<!-- table here -->

<pagination 
  ng-model="currentPage"
  total-items="todos.length"
  max-size="maxSize"  
  boundary-links="true">
</pagination>

<!-- items/page select here if you like -->

Manette

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);
  });
});

J'ai fait un plunker de travail pour référence.


Version héritée:

Vue

<!-- 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 -->

Manette

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);
  });
});

J'ai fait un plunker de travail pour référence.

Scotty.NET
la source
2
agréable et élégant. Il pourrait être amélioré en ajoutant un tri
Carlos Barcelona
3
L'attribut num-pages n'est plus nécessaire et est en lecture seule. Pas besoin de passer numPages. Voir les documents: angular-ui.github.io/bootstrap/#/pagination
kvetis
3
RESOLU: items-per-page est la propriété qui doit être définie dans l' paginationélément.
Bogac
1
^^^^ Pour tous les nouveaux lecteurs, voir le commentaire de Bogacs: les éléments par page sont maintenant nécessaires dans l'élément de pagination. Ne fonctionne pas sans cela.
IfTrue
14
<pagination> est désormais obsolète. Utilisez plutôt <uib-pagination>.
mnm du
88

J'ai récemment implémenté la pagination pour le site Built with Angular. Vous pouvez vérifier la source: https://github.com/angular/builtwith.angularjs.org

J'éviterais d'utiliser un filtre pour séparer les pages. Vous devez diviser les éléments en pages dans le contrôleur.

btford
la source
61
La solution est répartie sur plusieurs fichiers. Vous devez regarder au moins le contrôleur et la vue. Je ne vois pas comment cela justifie un downvote:Use your downvotes whenever you encounter an egregiously sloppy, no-effort-expended post, or an answer that is clearly and perhaps dangerously incorrect.
btford
2
Vous pouvez commencer à regarder la <div class = "pagination"> de index.html github.com/angular/builtwith.angularjs.org/blob/master/…
Jorge Nunez Newton
6
@btford Pourquoi voudriez-vous éviter d'utiliser un filtre?
CWSpear
4
J'ai voté pour contrebalancer le vote précédent, car je pensais que l'affiche offrait un exemple de qualité qui pouvait être utilisé pour répondre à la question d'origine.
RachelD
1
@btford Est-ce toujours une mauvaise idée de paginer en utilisant un filtre? Voici un plunkr paginant une liste via un filtre qui semble performant (au moins dans cet exemple trivial jusqu'à 10 000 000 de lignes): embed.plnkr.co/iWxWlCEvd6Uh8erUOyaF
Ryan Kimber
79

J'ai dû implémenter la pagination à plusieurs reprises avec Angular, et c'était toujours un peu pénible pour quelque chose que je pensais pouvoir être simplifié. J'ai utilisé certaines des idées présentées ici et ailleurs pour créer un module de pagination qui rend la pagination aussi simple que:

<ul>
    <li dir-paginate="item in items | itemsPerPage: 10">{{ item }}</li>
</ul>

// then somewhere else on the page ....

<dir-pagination-controls></dir-pagination-controls>

C'est tout. Il présente les caractéristiques suivantes:

  • Aucun code personnalisé n'est nécessaire dans votre contrôleur pour lier la collection itemsaux liens de pagination.
  • Vous n'êtes pas obligé d'utiliser une table ou une grille - vous pouvez paginer tout ce que vous pouvez répéter!
  • Délégués à ng-repeat, afin que vous puissiez utiliser n'importe quelle expression qui pourrait être valablement utilisée dans un ng-repeat, y compris le filtrage, l'ordre, etc.
  • Fonctionne sur tous les contrôleurs - la pagination-controlsdirective n'a pas besoin de connaître le contexte dans lequel la paginatedirective est appelée.

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

Pour ceux qui recherchent une solution "plug and play", je pense que vous la trouverez utile.

Code

Le code est disponible ici sur GitHub et comprend un assez bon ensemble de tests:

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

Si vous êtes intéressé, j'ai également écrit un court article avec un peu plus d'informations sur la conception du module: http://www.michaelbromley.co.uk/blog/108/paginate-almost-anything-in-angularjs/

Michael Bromley
la source
Salut @michael bromley, j'essaie avec angularUtils. J'ai ajouté des fichiers dirPangination.js et dirPagination.tpl.html à mon projet. Mais j'ai commencé à recevoir une erreur comme "[$ compile: tpload] Impossible de charger le modèle: directives / pagination / dirPagination.tpl.html". J'avais essayé de mettre ce fichier html dans le dossier de directives de mon projet. Mais je n'ai pas réussi. J'ai les doutes suivants: 1. Où mettre dirPagination.tpl.html dans le projet (comme j'utilise ruby ​​sur rails avec Angularjs)?
Vieenay Siingh
2
Neat, vous m'avez gagné au moment où j'ai lu que la pagination pouvait être n'importe où dans la page :) L'utilise actuellement et fonctionne bien.
diosney
4
Il s'agit de la meilleure directive de radiomessagerie pour angulaire. C'est probablement la solution de pagination la plus simple que j'ai jamais vue. J'étais en train de paginer plusieurs tables par vue chacune avec son propre contrôle de pagination isolé en 15 minutes. Le tout avec deux lignes de code par fichier .jade. Tout ce que je peux dire, c'est WOW. Impressionnant!
jrista
6
Je peux témoigner du caractère génial de cette directive, j'ai eu une répétition ng complexe et elle ne l'a pas gérée. Configuration super facile.
gkiely
1
Votre méthode "tracker ()" sauve ma journée. J'avais un comportement horrible et rare sans ça.
Leopoldo Sanczyk
63

Je viens de faire un JSFiddle qui montre la pagination + recherche + ordre par sur chaque colonne en utilisant le code btford: http://jsfiddle.net/SAWsA/11/

Spir
la source
4
Merci pour le violon. C'est très utile. Question cependant: comment implémenteriez-vous le tri sur l'ensemble des résultats au lieu de ce qui est sur la page actuelle?
super9
5
Notez que le tri ne fonctionne que sur la page courante ... Il ne trie pas tout le tableau. La pagination doit être refaite à chaque fois que vous changez l'ordre de tri
dgn
3
@Spir: Oui, la recherche fonctionne, mais pas le tri. Si vous inversez le tri de la page 1, seule cette page est réorganisée, au lieu d'afficher les éléments 9, 20 et co
dgn
1
@AleckLandgraf j'ai essayé d'ajouter $ scope.search mais ii n'affiche toujours pas la liste triée correcte. s'il vous plaît laissez-moi savoir ce que vous avez essayé ou ajouté d'autre
anam
1
@simmisimmi @Spir @scenario il y a un bogue en bas du javascript: new_sorting_orderdevrait être newSortingOrder. Corrigez cela, ajoutez le @scope.search();et vous verrez les choses se trier comme prévu, et les icônes de tri seront également mises à jour. (Exécutez le violon avec la console de débogage de votre navigateur ouverte (en chrome, F12, onglet console) et c'est évident).
Dax Fohl
15

J'ai mis à jour le plunkr http://plnkr.co/edit/FUeWwDu0XzO51lyLAEIA?p=preview de Scotty.NET afin qu'il utilise des versions plus récentes de angular, angular-ui et bootstrap.

Manette

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();
  };

});

Composant d'interface de démarrage

 <pagination boundary-links="true" 
    max-size="3" 
    items-per-page="itemsPerPage"
    total-items="todos.length" 
    ng-model="currentPage" 
    ng-change="pageChanged()"></pagination>
user2176745
la source
cette solution mise à jour a vraiment répondu à mes besoins. Merci beaucoup.
Suraj Lama le
10

Il s'agit d'une solution javascript pure que j'ai enveloppé comme un service angulaire pour implémenter la logique de pagination comme dans les résultats de recherche Google.

Démo de travail sur CodePen à http://codepen.io/cornflourblue/pen/KVeaQL/

Détails et explications sur cet article de 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
        };
    }
}
Jason
la source
J'ai utilisé votre approche mais le problème est que si je veux utiliser des index pour la commande à la page, il est toujours affiché comme 0-9 ...
vaske
4

J'ai extrait les bits pertinents ici. Il s'agit d'un téléavertisseur tabulaire `` sans fioritures '', donc le tri ou le filtrage n'est pas inclus. N'hésitez pas à modifier / ajouter au besoin:

     //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>

msyed
la source
4

Solution ci-dessous assez 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) "> 

Voici un exemple de jsfiddle

Sh4m
la source
3

Pour tous ceux qui ont du mal comme moi à créer un paginateur pour une table, je poste ceci. Donc, selon vous:

          <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" >

Dans vos 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);
              };
            });     
K.Mouna
la source
Il y avait des réponses avec autant de votes positifs et positifs .. mais aucune n'a fonctionné pour moi .. mais celle-ci combinée avec la réponse de @svarog a fonctionné comme un charme pour moi.
Rai
3

Depuis Angular 1.4, le limitTofiltre accepte également un deuxième argument optionnelbegin

De la documentation :

{{limitTo_expression | limitTo: limit: begin}}

begin (facultatif) string | number
Index auquel commencer la limitation. En tant qu'indice négatif, le début indique un décalage par rapport à la fin de l'entrée. Par défaut à 0.

Vous n'avez donc pas besoin de créer une nouvelle directive , cet argument peut être utilisé pour définir le décalage de la pagination

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

Vous pouvez facilement le faire en utilisant la directive Bootstrap UI.

Cette réponse est une modification de la réponse donnée par @ Scotty.NET, j'ai changé le code car la <pagination>directive est obsolète maintenant.

Le code suivant génère la pagination:

<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>

Pour le rendre fonctionnel, utilisez ceci dans votre contrôleur:

$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();

Référez-vous à ceci pour plus d'options de pagination: Directive de pagination de l'interface utilisateur Bootstrap

Astitva Srivastava
la source
2

pagination ng-répétition

    <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>
Asad
la source
1

Les messages précédents recommandaient essentiellement comment créer vous-même une pagination. Si vous êtes comme moi et que vous préférez une directive finie, je viens d'en trouver une excellente appelée ngTable . Il prend en charge le tri, le filtrage et la pagination.

C'est une solution très propre, tout ce dont vous avez besoin selon vous:

   <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>

Et dans le contrôleur:

$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));
    }
});

Lien vers GitHub: https://github.com/esvit/ng-table/

Carlos Barcelona
la source
1

Angular-Paging

est un merveilleux choix

Une directive pour faciliter la pagination de grands ensembles de données tout en exigeant le strict minimum d'informations de pagination réelles. Nous sommes très dépendants du serveur pour les résultats de "filtrage" dans ce schéma de pagination. L'idée centrale étant que nous voulons uniquement conserver la «page» active des éléments - plutôt que de conserver la liste complète des éléments en mémoire et de paginer côté client.

sendreams
la source
1

Vieille question, mais comme je pense que mon approche est un peu différente et moins complexe, je partagerai cela et j'espère que quelqu'un d'autre que moi le trouvera utile.

Ce que j'ai trouvé être une solution simple et petite à la pagination est de combiner une directive avec un filtre qui utilise les mêmes variables de portée.

Pour implémenter cela, vous ajoutez le filtre sur le tableau et ajoutez le directiv comme celui-ci

<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 et p_Step sont des variables d'étendue qui peuvent être personnalisées dans l'étendue, sinon la valeur par défaut de p_Size est 5 et p_Step est 1.

Lorsqu'une étape est modifiée dans la pagination, le p_Step est mis à jour et déclenchera un nouveau filtrage par le filtre cust_pagination. Le filtre cust_pagination coupe ensuite le tableau en fonction de la valeur p_Step comme ci-dessous et ne renvoie que les enregistrements actifs sélectionnés dans la section de pagination

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

DEMO Voir la solution complète dans ce plongeur

Marcus Höglund
la source
0

Voilà mon exemple. Bouton sélectionné au milieu de la liste Contrôleur. config >>>

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

Logique de pagination:

/*
     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);
    });

et ma vue sur bootstap

<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 >

C'est utile

Alexey
la source
0

J'aimerais pouvoir commenter, mais je vais devoir laisser ceci ici:

La réponse de Scotty.NET et le rétablissement de user2176745 pour les versions ultérieures sont tous deux excellents, mais ils manquent tous les deux quelque chose sur lequel ma version d'AngularJS (v1.3.15) se casse:

i n'est pas défini dans $ scope.makeTodos.

En tant que tel, le remplacement par cette fonction le corrige pour les versions angulaires plus récentes.

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

Présentation : pagination à l'aide

 - ng-repeat
 - uib-pagination

Voir :

<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>

Contrôleur 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();

}]);
Riddhi Gohil
la source
0

Je voudrais ajouter ma solution qui fonctionne avec ngRepeatet les filtres que vous utilisez avec elle sans utiliser un $watchou un tableau en tranches.

Vos résultats de filtrage seront paginés!

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;
    };
}]);

Dans le HTML, assurez-vous d'appliquer vos filtres à l' ngRepeat avant du filtre de pagination.

<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>
Jonathan Czitkovics
la source