Jak zrobić stronicowanie w AngularJS?


254

Mam w pamięci zestaw danych zawierający około 1000 elementów i próbuję utworzyć pager dla tego zestawu danych, ale nie jestem pewien, jak to zrobić.

Używam niestandardowej funkcji filtrowania do filtrowania wyników, i to działa dobrze, ale jakoś muszę uzyskać liczbę stron.

Jakieś wskazówki?


Odpowiedzi:


285

Angular UI Bootstrap - dyrektywa do paginacji

Sprawdź UI Bootstrap „s dyrektywę paginacji . Skończyło się na tym, że użyłem go, a nie tego, co tu zamieszczono, ponieważ ma wystarczającą liczbę funkcji do mojego obecnego użycia i ma dokładną specyfikację testu, aby mu towarzyszyć.

Widok

<!-- table here -->

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

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

Kontroler

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

Zrobiłem działającego plunkera dla odniesienia.


Starsza wersja:

Widok

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

Kontroler

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

Zrobiłem działającego plunkera dla odniesienia.


2
ładny i elegancki. Można to poprawić, dodając coś
Carlos Barcelona

3
Atrybut num-pages nie jest już potrzebny i jest tylko do odczytu. Nie musisz przekazywać numPages. Zobacz dokumentację: angular-ui.github.io/bootstrap/#/pagination
kvetis

3
ROZWIĄZANE: items-per-page jest właściwością, którą należy ustawić w paginationelemencie.
Bogac

1
^^^^ Dla wszystkich nowych czytelników patrz komentarz Bogacsa: elementy na stronę są teraz potrzebne w elemencie pagination. Bez tego nie działa.
Prawda

14
<pagination> jest teraz przestarzałe. Zamiast tego użyj <uib-pagination>.
mnm

88

Niedawno wdrożyłem stronicowanie dla witryny Built with Angular. Możesz kasować źródło: https://github.com/angular/builtwith.angularjs.org

Unikałbym używania filtra do oddzielania stron. Powinieneś podzielić elementy na strony w kontrolerze.


61
Rozwiązanie jest rozłożone na wiele plików. Musisz zajrzeć przynajmniej do kontrolera i widoku. Nie rozumiem, jak to uzasadnia opinię: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
Możesz zacząć przeglądać <div class = "pagination"> w index.html github.com/angular/builtwith.angularjs.org/blob/master/…
Jorge Nunez Newton

6
@btford Dlaczego miałbyś unikać używania filtra?
CWSpear

4
Głosowałem za odrzuceniem poprzedniego głosowania za odrzuceniem, ponieważ czułem, że plakat stanowi przykład jakości, który można wykorzystać do udzielenia odpowiedzi na pierwotne pytanie.
RachelD,

1
@btford Czy nadal złym pomysłem jest paginacja przy użyciu filtra? Oto plunkr paginujący listę za pomocą filtra, który wydaje się skuteczny (przynajmniej w tym trywialnym przykładzie do 10 000 000 wierszy): embed.plnkr.co/iWxWlCEvd6Uh8erUOyaF
Ryan Kimber

79

Kilkakrotnie musiałem wdrożyć paginację za pomocą Angulara i zawsze było to trochę uciążliwe dla czegoś, co moim zdaniem można uprościć. Wykorzystałem niektóre z pomysłów przedstawionych tutaj i gdzie indziej, aby stworzyć moduł stronicowania, który czyni paginację tak prostą jak:

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

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

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

Otóż ​​to. Ma następujące funkcje:

  • W kontrolerze nie jest potrzebny niestandardowy kod, aby powiązać kolekcję itemsz linkami stronicowania.
  • Nie musisz używać tabeli ani widoku siatki - możesz podzielić na strony wszystko, co możesz powtórzyć!
  • Deleguje do ng-repeat, abyś mógł użyć dowolnego wyrażenia, które może być poprawnie użyte w ng-repeat, w tym filtrowania, porządkowania itp.
  • Działa na różnych kontrolerach - pagination-controlsdyrektywa nie musi nic wiedzieć na temat kontekstu, w którym paginatedyrektywa jest wywoływana.

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

Dla tych, którzy szukają rozwiązania typu „plug and play”, myślę, że okaże się to przydatne.

Kod

Kod jest dostępny tutaj na GitHub i zawiera całkiem niezły zestaw testów:

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

Jeśli jesteś zainteresowany, napisałem również krótki kawałek z nieco większym wglądem w projekt modułu: http://www.michaelbromley.co.uk/blog/108/paginate-almost-anything-in-angularjs/


Cześć @michael bromley, Próbuję z angularUtils. Do mojego projektu dodałem pliki dirPangination.js i dirPagination.tpl.html. Ale zacząłem pojawiać się błąd, taki jak „[$ compile: tpload] Nie udało się załadować szablonu: dyrektyw / pagination / dirPagination.tpl.html”. Próbowałem umieścić ten plik HTML w folderze dyrektyw mojego projektu. Ale nie miałem sukcesu. Mam następujące wątpliwości: 1. Gdzie umieścić dirPagination.tpl.html w projekcie (ponieważ używam rubinu na szynach z Angularjs)?
Vieenay Siingh,

2
Zgrabnie, zyskałeś mnie w momencie, gdy przeczytałem, że paginacja może być w dowolnym miejscu na stronie :) Obecnie go używam i działa płynnie.
diosney,

4
Jest to najlepsza dyrektywa stronicowania dla kątów. Jest to prawdopodobnie najprostsze rozwiązanie do stronicowania, jakie kiedykolwiek widziałem. Byłem gotowy i stronicowałem wiele tabel na widok, każdy z własną izolowaną kontrolą stronicowania w 15 minut. Wszystko z dwoma liniami kodu na plik .jade. Wszystko, co mogę powiedzieć, to WOW. Niesamowite!
jrista

6
Mogę poręczyć za wspaniałość tej dyrektywy, miałem skomplikowane powtórzenie ng i nie poradziłem sobie z tym. Bardzo łatwa konfiguracja.
gkiely

1
Twoja metoda „tracker ()” uratuje mi dzień. Bez tego miałem okropne i rzadkie zachowanie.
Leopoldo Sanczyk,

63

Właśnie utworzyłem JSFiddle, który pokazuje podział na strony + wyszukiwanie + porządkowanie według każdej kolumny za pomocą kodu btford: http://jsfiddle.net/SAWsA/11/


4
Dzięki za skrzypce. To jest bardzo użyteczne. Pytanie: jak zaimplementowałbyś sortowanie w całym zestawie wyników zamiast tego, co jest na bieżącej stronie?
super9

5
Zauważ, że sortowanie działa tylko na bieżącej stronie ... Nie sortuje całej tablicy. Podział na strony należy powtarzać za każdym razem, gdy zmieniasz porządek sortowania
dgn

3
@Spir: Tak, wyszukiwanie działa, ale nie sortuje. Jeśli odwrotnej sortowania na stronie 1, tylko ta strona jest kolejność, zamiast wyświetlania elementów 9, 20 i CO
DGN

1
@AleckLandgraf Próbowałem dodać $ scope.search, ale ii nadal nie wyświetla poprawnie posortowanej listy. daj mi znać, co jeszcze wypróbowałeś lub dodałeś
anam

1
@simmisimmi @Spir @scenario na dole javascript jest błąd: new_sorting_orderpowinien być newSortingOrder. Napraw to, dodaj @scope.search();, a zobaczysz, że rzeczy są sortowane zgodnie z oczekiwaniami, a ikony sortowania również się aktualizują. (Uruchom skrzypce przy otwartej konsoli debugowania przeglądarki (w chrome, F12, karta konsoli) i jest to oczywiste).
Dax Fohl,

15

Zaktualizowałem plunkr Scotty.NET http://plnkr.co/edit/FUeWwDu0XzO51lyLAEIA?p=preview, aby korzystał z nowszych wersji angular, angular -ui i bootstrap.

Kontroler

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

});

Komponent interfejsu użytkownika Bootstrap

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

to zaktualizowane rozwiązanie naprawdę spełniło moje potrzeby. Wielkie dzięki.
Suraj Lama,

10

Jest to czyste rozwiązanie JavaScript, które zapakowałem jako usługę Angular, aby zaimplementować logikę paginacji, tak jak w wynikach wyszukiwania Google.

Działające demo na CodePen pod adresem http://codepen.io/cornflourblue/pen/KVeaQL/

Szczegóły i wyjaśnienia na tym blogu

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

Użyłem twojego podejścia, ale problem polega na tym, że jeśli chcę używać indeksów do zamawiania na stronie, to zawsze jest wyświetlane jako 0-9 ...
vaske

4

Wyodrębniłem tutaj odpowiednie fragmenty. Jest to pager tabelaryczny „bez fanaberii”, więc sortowanie lub filtrowanie nie jest uwzględnione. W razie potrzeby możesz zmieniać / dodawać:

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


4

Poniżej rozwiązanie dość proste.

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

Oto przykładowy plik jsfiddle



3

Dla każdego, kto ma trudności z utworzeniem paginatora dla stołu, zamieszczam to. Twoim zdaniem:

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

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

Były odpowiedzi z tyloma pozytywnymi opiniami i pozytywami .. ale żadna nie działała dla mnie .. ale ta w połączeniu z odpowiedzią @svarog działała dla mnie jak urok.
Rai


3

Od wersji Angular 1.4 limitTofiltr akceptuje również drugi opcjonalny argumentbegin

Z dokumentów :

{{limitTo_expression | limitTo: limit: start}}

begin (opcjonalne) string | number
Indeks, od którego należy zacząć ograniczenie. Jako indeks ujemny, początek wskazuje przesunięcie od końca danych wejściowych. Domyślnie 0.

Nie musisz więc tworzyć nowej dyrektywy. Tego argumentu można użyć do ustawienia przesunięcia stronicowania

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

3

Możesz to łatwo zrobić za pomocą dyrektywy Bootstrap UI.

Ta odpowiedź jest modyfikacją odpowiedzi udzielonej przez @ Scotty.NET, zmieniłem kod, ponieważ <pagination> dyrektywa jest już nieaktualna.

Poniższy kod generuje paginację:

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

Aby to działało, użyj tego w swoim kontrolerze:

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

Więcej informacji na temat paginacji znajduje się w: Bootstrap UI Pagination Directive


2

powtarzanie stron

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

1

Poprzednie wiadomości w zasadzie zalecały samodzielne tworzenie stronicowania. Jeśli jesteś podobny do mnie i wolisz skończoną dyrektywę, właśnie znalazłem świetną o nazwie ngTable . Obsługuje sortowanie, filtrowanie i paginację.

Jest to bardzo czyste rozwiązanie, wszystko, czego potrzebujesz, według Twojego widoku:

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

I w kontrolerze:

$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 do GitHub: https://github.com/esvit/ng-table/


1

Stronicowanie kątowe

to wspaniały wybór

Dyrektywa ułatwiająca stronicowanie dużych zestawów danych, wymagająca jednak absolutnego minimum rzeczywistych informacji o stronicowaniu. Jesteśmy bardzo zależni od serwera w zakresie „filtrowania” wyników w tym schemacie stronicowania. Główną ideą jest to, że chcemy tylko przechowywać aktywną „stronę” elementów - zamiast trzymać całą listę elementów w pamięci i stronicować po stronie klienta.


1

Stare pytanie, ale ponieważ uważam, że moje podejście jest nieco inne i mniej złożone, podzielę się tym i mam nadzieję, że ktoś poza mną okaże się przydatny.

To, co uznałem za łatwe i małe rozwiązanie podziału na strony, to połączenie dyrektywy z filtrem, który używa tych samych zmiennych zakresu.

Aby to zaimplementować, dodajesz filtr do tablicy i dodajesz dyrektywę w ten sposób

<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 i p_Step są zmiennymi zakresu, które można dostosować w zakresie, w przeciwnym razie domyślna wartość p_Size to 5, a p_Step to 1.

Gdy zmienia się krok w paginacji, p_Step jest aktualizowany i wyzwala nowe filtrowanie według filtra cust_pagination. Filtr cust_pagination wycina następnie tablicę w zależności od wartości p_Step, jak poniżej, i zwraca tylko aktywne rekordy wybrane w sekcji stronicowania

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

DEMO Zobacz kompletne rozwiązanie w tym dziale


0

Oto mój przykład. Wybrany przycisk pośrodku na liście Kontroler. config >>>

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

Logika stronicowania:

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

i mój pogląd na 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 >

To jest użyteczne


0

Chciałbym móc komentować, ale muszę to zostawić tutaj:

Odpowiedzi Scotty.NET i ponowne wykonanie user2176745 dla późniejszych wersji są świetne, ale w obu brakuje czegoś, co psuje moja wersja AngularJS (v1.3.15):

nie jest zdefiniowany w $ scope.makeTodos.

W związku z tym zastąpienie tą funkcją naprawia ją dla nowszych wersji kątowych.

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

0

Przegląd : Korzystanie z paginacji

 - ng-repeat
 - uib-pagination

Zobacz :

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

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

}]);

0

Chciałbym dodać moje rozwiązanie, które działa z ngRepeatfiltrami, których używasz bez użycia $watchtablicy lub plastra.

Twoje wyniki filtrów zostaną podzielone na strony!

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

W kodzie HTML upewnij się, że zastosujesz filtry do filtra ngRepeat przed paginacją.

<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>
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.