Wie mache ich Paging in AngularJS?

254

Ich habe einen Datensatz mit ungefähr 1000 Elementen im Speicher und versuche, einen Pager für diesen Datensatz zu erstellen, bin mir jedoch nicht sicher, wie ich dies tun soll.

Ich verwende eine benutzerdefinierte Filterfunktion, um die Ergebnisse zu filtern, und das funktioniert gut, aber irgendwie muss ich die Anzahl der Seiten herausholen.

Irgendwelche Hinweise?

Glimmer
quelle

Antworten:

285

Angular UI Bootstrap - Paginierungsrichtlinie

Check out UI Bootstrap ‚s Paginierung Richtlinie . Am Ende habe ich es eher verwendet als das, was hier veröffentlicht wird, da es über genügend Funktionen für meine aktuelle Verwendung verfügt und eine gründliche Testspezifikation enthält .

Aussicht

<!-- table here -->

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

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

Regler

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

Ich habe einen funktionierenden Plunker als Referenz gemacht.


Legacy-Version:

Aussicht

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

Regler

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

Ich habe einen funktionierenden Plunker als Referenz gemacht.

Scotty.NET
quelle
2
schön und elegant. Es könnte durch Hinzufügen einer Sorte verbessert werden
Carlos Barcelona
3
Das Attribut num-pages wird nicht mehr benötigt und ist schreibgeschützt. Keine Notwendigkeit, numPages zu übergeben. Siehe die Dokumente: angle-ui.github.io/bootstrap/#/pagination
kvetis
3
Gelöst: Elemente pro Seite ist die Eigenschaft, die im paginationElement festgelegt werden muss.
Bogac
1
^^^^ Für alle neuen Leser siehe Bogacs Kommentar: Artikel pro Seite werden jetzt im Paginierungselement benötigt. Funktioniert nicht ohne.
IfTrue
14
<Paginierung> ist jetzt veraltet. Verwenden Sie stattdessen <uib-pagination>.
Mnm
88

Ich habe kürzlich Paging für die Site "Built with Angular" implementiert. Sie können die Quelle überprüfen : https://github.com/angular/builtwith.angularjs.org

Ich würde es vermeiden, einen Filter zum Trennen der Seiten zu verwenden. Sie sollten die Elemente innerhalb des Controllers in Seiten aufteilen.

Btford
quelle
61
Die Lösung ist auf mehrere Dateien verteilt. Sie müssen mindestens den Controller und die Ansicht anzeigen. Ich sehe nicht, wie das eine Ablehnung rechtfertigt: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
Sie können sich die <div class = "pagination"> von index.html ansehen. Github.com/angular/builtwith.angularjs.org/blob/master/…
Jorge Nunez Newton
6
@btford Warum sollten Sie die Verwendung eines Filters vermeiden?
CWSpear
4
Ich habe nach oben gestimmt, um der vorherigen nach unten gerichteten Abstimmung entgegenzuwirken, weil ich der Meinung war, dass das Poster ein Qualitätsbeispiel darstellt, mit dem die ursprüngliche Frage beantwortet werden kann.
RachelD
1
@btford Ist es immer noch eine schlechte Idee, mit einem Filter zu paginieren? Hier ist ein Plunkr, der eine Liste über einen Filter paginiert, der performant erscheint (zumindest in diesem trivialen Beispiel bis zu 10 000 000 Zeilen): embedded.plnkr.co/iWxWlCEvd6Uh8erUOyaF
Ryan Kimber
79

Ich musste einige Male mit Angular Paginierung implementieren, und es war immer ein bisschen schmerzhaft für etwas, von dem ich glaubte, dass es vereinfacht werden könnte. Ich habe einige der hier und anderswo vorgestellten Ideen verwendet, um ein Paginierungsmodul zu erstellen, das die Paginierung so einfach macht wie:

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

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

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

Das ist es. Es hat die folgenden Funktionen:

  • In Ihrem Controller ist kein benutzerdefinierter Code erforderlich, um die Sammlung itemsmit den Paginierungslinks zu verknüpfen.
  • Sie sind nicht an die Verwendung einer Tabelle oder einer Rasteransicht gebunden - Sie können alles paginieren, was Sie wiederholen können!
  • Delegiert an ng-repeat, sodass Sie jeden Ausdruck verwenden können, der in einem gültig verwendet werden kann ng-repeat, einschließlich Filtern, Bestellen usw.
  • Funktioniert über Controller hinweg - die pagination-controlsDirektive muss nichts über den Kontext wissen, in dem die paginateDirektive aufgerufen wird.

Demo: http://plnkr.co/edit/Wtkv71LIqUR4OhzhgpqL?p=preview

Für diejenigen, die nach einer "Plug and Play" -Lösung suchen, finde ich das nützlich.

Code

Der Code ist hier auf GitHub verfügbar und enthält eine Reihe guter Tests:

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

Wenn Sie interessiert sind, habe ich auch ein kurzes Stück mit etwas mehr Einblick in das Design des Moduls geschrieben: http://www.michaelbromley.co.uk/blog/108/paginate-almost-anything-in-angularjs/

Michael Bromley
quelle
Hallo @michael bromley, ich versuche es mit angularUtils. Ich habe meinem Projekt die Dateien dirPangination.js und dirPagination.tpl.html hinzugefügt. Aber ich bekam Fehler wie "[$ compile: tpload] Fehler beim Laden der Vorlage: directives / pagination / dirPagination.tpl.html". Ich hatte versucht, diese HTML-Datei in den Direktivenordner meines Projekts zu legen. Aber ich hatte keinen Erfolg. Ich habe folgende Zweifel: 1. Wo soll dirPagination.tpl.html in das Projekt eingefügt werden (da ich mit Angularjs Ruby on Rails verwende)?
Vieenay Siingh
2
Ordentlich, Sie haben mich in dem Moment gewonnen, in dem ich gelesen habe, dass die Paginierung irgendwo auf der Seite sein könnte :) Derzeit wird sie verwendet und funktioniert reibungslos.
Diosney
4
Dies ist die beste Paging-Direktive für Winkel. Es ist wahrscheinlich die einfachste Lösung für Paging, die ich je gesehen habe. Ich war auf und habe in 15 Minuten mehrere Tabellen pro Ansicht mit jeweils einer eigenen isolierten Paging-Steuerung ausgelagert. Alle mit zwei Codezeilen pro JAD-Datei. Alles was ich sagen kann ist WOW. Genial!
jrista
6
Ich kann für die Großartigkeit dieser Richtlinie bürgen, ich hatte eine komplexe ng-Wiederholung und es handhabte es keine Probleme. Super einfaches Setup.
Gkiely
1
Ihre "tracker ()" - Methode rettet meinen Tag. Ich hatte ein schreckliches und seltenes Verhalten ohne es.
Leopoldo Sanczyk
63

Ich habe gerade eine JSFiddle erstellt, die Paginierung + Suche + Reihenfolge nach in jeder Spalte mit dem Btford-Code anzeigt: http://jsfiddle.net/SAWsA/11/

Spir
quelle
4
Danke für die Geige. Es ist sehr nützlich. Frage: Wie würden Sie die Sortierung über die gesamte Ergebnismenge implementieren, anstatt über die aktuelle Seite?
Super9
5
Beachten Sie, dass die Sortierung nur auf der aktuellen Seite funktioniert ... Sie sortiert nicht das gesamte Array. Die Paginierung muss jedes Mal wiederholt werden, wenn Sie die Sortierreihenfolge ändern
dgn
3
@Spir: Ja, die Suche funktioniert, aber nicht das Sortieren. Wenn Sie die Sortierung auf Seite umzukehren, werden nur diese Seite neu geordnet, sondern die Elemente der Anzeige 9, 20 und co
DGN
1
@AleckLandgraf Ich habe versucht, $ scope.search hinzuzufügen, aber ii zeigt immer noch nicht die richtige sortierte Liste an. Bitte lassen Sie mich wissen, was Sie sonst noch versucht oder hinzugefügt haben
anam
1
@simmisimmi @Spir @scenario Es gibt einen Fehler am Ende des Javascript: new_sorting_ordersollte sein newSortingOrder. Beheben Sie das, fügen Sie das hinzu @scope.search();, und Sie werden sehen, dass die Dinge wie erwartet sortiert werden und die Sortiersymbole ebenfalls aktualisiert werden. (Führen Sie die Geige mit geöffneter Debugging-Konsole Ihres Browsers aus (in Chrome, F12, Registerkarte "Konsole"), und es ist offensichtlich).
Dax Fohl
15

Ich habe Scotty.NETs plunkr http://plnkr.co/edit/FUeWwDu0XzO51lyLAEIA?p=preview aktualisiert, sodass neuere Versionen von angle, angle -ui und bootstrap verwendet werden.

Regler

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

});

Bootstrap-UI-Komponente

 <pagination boundary-links="true" 
    max-size="3" 
    items-per-page="itemsPerPage"
    total-items="todos.length" 
    ng-model="currentPage" 
    ng-change="pageChanged()"></pagination>
user2176745
quelle
Diese aktualisierte Lösung hat meine Anforderungen wirklich erfüllt. Vielen Dank.
Suraj Lama
10

Dies ist eine reine Javascript-Lösung, die ich als Angular-Dienst verpackt habe, um die Paginierungslogik wie in Google-Suchergebnissen zu implementieren.

Arbeitsdemo zu CodePen unter http://codepen.io/cornflourblue/pen/KVeaQL/

Details und Erklärungen in diesem Blogbeitrag

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
quelle
Ich habe Ihren Ansatz verwendet, aber das Problem ist, wenn ich Indizes für die Bestellung auf Seite verwenden möchte, wird es immer als 0-9 angezeigt ...
Vaske
4

Ich habe hier die relevanten Bits extrahiert. Dies ist ein tabellarischer Pager ohne Schnickschnack, daher ist das Sortieren oder Filtern nicht enthalten. Fühlen Sie sich frei, nach Bedarf zu ändern / hinzuzufügen:

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

Unten Lösung ganz einfach.

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

Hier ist ein Beispiel für jsfiddle

Sh4m
quelle
3

Für alle, die es schwierig finden wie ich, einen Paginator für einen Tisch zu erstellen, poste ich dies. Also aus Ihrer Sicht:

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

In Ihren eckigen Js:

  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
quelle
Es gab Antworten mit so vielen positiven und positiven Stimmen ... aber keine funktionierte für mich ... aber diese in Kombination mit der Antwort von @svarog wirkte wie ein Zauber für mich.
Rai
3

Ich verwende diese Paginierungsbibliothek von Drittanbietern und sie funktioniert gut. Es kann lokale / entfernte Datenquellen verarbeiten und ist sehr konfigurierbar.

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

<dir-pagination-controls
    [max-size=""]
    [direction-links=""]
    [boundary-links=""]
    [on-page-change=""]
    [pagination-id=""]
    [template-url=""]
    [auto-hide=""]>
    </dir-pagination-controls>
Henry Zou
quelle
3

Seit Angular 1.4 limitToakzeptiert der Filter auch ein zweites optionales Argumentbegin

Aus den Dokumenten :

{{limitTo_expression | limitTo: limit: begin}}

begin (optional) string | number
Index, bei dem die Begrenzung beginnen soll. Als negativer Index gibt begin einen Versatz vom Ende der Eingabe an. Der Standardwert ist 0.

Sie müssen also keine neue Direktive erstellen . Mit diesem Argument können Sie den Versatz der Paginierung festlegen

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

Sie können dies einfach mit der Bootstrap-UI-Direktive tun.

Diese Antwort ist eine Änderung der Antwort von @ Scotty.NET. Ich habe den Code geändert, da die <pagination>Direktive jetzt veraltet ist.

Der folgende Code generiert die Paginierung:

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

Verwenden Sie dies in Ihrem Controller, um es funktionsfähig zu machen:

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

Weitere Optionen für die Paginierung finden Sie hier: Paginierungsrichtlinie für die Bootstrap-Benutzeroberfläche

Astitva Srivastava
quelle
2

ng-wiederholte Paginierung

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

In früheren Nachrichten wurde grundsätzlich empfohlen, wie Sie ein Paging selbst erstellen können. Wenn Sie wie ich sind und eine fertige Direktive bevorzugen, habe ich gerade eine großartige gefunden, die ngTable heißt . Es unterstützt das Sortieren, Filtern und Paginieren.

Es ist eine sehr saubere Lösung, alles was Sie aus Ihrer Sicht brauchen:

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

Und im Controller:

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

Link zu GitHub: https://github.com/esvit/ng-table/

Carlos Barcelona
quelle
1

Angular-Paging

ist eine wunderbare Wahl

Eine Richtlinie, die das Paging großer Datenmengen unterstützt und gleichzeitig das Minimum an tatsächlichen Paging-Informationen erfordert. Wir sind sehr abhängig vom Server, um die Ergebnisse dieses Paging-Schemas zu "filtern". Die zentrale Idee ist, dass wir nur die aktive "Seite" von Elementen halten möchten - anstatt die gesamte Liste von Elementen im Speicher zu halten und auf der Clientseite zu blättern.

sendreams
quelle
1

Alte Frage, aber da ich denke, dass mein Ansatz etwas anders und weniger komplex ist, werde ich dies teilen und hoffen, dass jemand außer mir es nützlich findet.

Was ich als einfache und kleine Lösung für die Paginierung empfunden habe, ist die Kombination einer Direktive mit einem Filter, der dieselben Bereichsvariablen verwendet.

Um dies zu implementieren, fügen Sie den Filter zum Array hinzu und fügen die Direktive wie folgt hinzu

<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 und p_Step sind Bereichsvariablen, die im Bereich angepasst werden können. Andernfalls beträgt der Standardwert von p_Size 5 und p_Step 1.

Wenn ein Schritt in der Paginierung geändert wird, wird der p_Step aktualisiert und löst eine neue Filterung durch den cust_pagination-Filter aus. Der cust_pagination-Filter schneidet dann das Array in Abhängigkeit vom p_Step-Wert wie unten auf und gibt nur die im Paginierungsabschnitt ausgewählten aktiven Datensätze zurück

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

DEMO Sehen Sie sich die Komplettlösung in diesem Plunker an

Marcus Höglund
quelle
0

Da ist mein Beispiel. Ausgewählte Schaltfläche in der Mitte der Liste Controller. config >>>

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

Logik für die Paginierung:

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

und meine Sicht auf 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 >

Es ist nützlich

Alexey
quelle
0

Ich wünschte, ich könnte einen Kommentar abgeben, aber ich muss das hier einfach belassen:

Die Antwort von Scotty.NET und die Wiederholung von user2176745 für spätere Versionen sind beide großartig, aber beide vermissen etwas, auf das meine Version von AngularJS (v1.3.15) verzichtet:

Ich bin nicht in $ scope.makeTodos definiert.

Das Ersetzen durch diese Funktion behebt sie daher für neuere Winkelversionen.

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

Übersicht : Paginierung mit

 - ng-repeat
 - uib-pagination

Ansicht :

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

JS Controller :

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

Ich möchte meine Lösung hinzufügen, die funktioniert, ngRepeatund Filter, die Sie damit verwenden, ohne ein $watchoder ein in Scheiben geschnittenes Array zu verwenden.

Ihre Filterergebnisse werden paginiert!

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

Stellen Sie im HTML sicher, dass Sie Ihre Filter auf den Filter ngRepeat vor dem Paginieren anwenden .

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