Pagination pada daftar menggunakan ng-repeat


130

Saya mencoba menambahkan halaman ke daftar saya. Saya mengikuti tutorial AngularJS, tutorial tentang smartphone dan saya mencoba menampilkan hanya sejumlah objek. Ini file html saya:

  <div class='container-fluid'>
    <div class='row-fluid'>
        <div class='span2'>
            Search: <input ng-model='searchBar'>
            Sort by: 
            <select ng-model='orderProp'>
                <option value='name'>Alphabetical</option>
                <option value='age'>Newest</option>
            </select>
            You selected the phones to be ordered by: {{orderProp}}
        </div>

        <div class='span10'>
          <select ng-model='limit'>
            <option value='5'>Show 5 per page</option>
            <option value='10'>Show 10 per page</option>
            <option value='15'>Show 15 per page</option>
            <option value='20'>Show 20 per page</option>
          </select>
          <ul class='phones'>
            <li class='thumbnail' ng-repeat='phone in phones | filter:searchBar | orderBy:orderProp | limitTo:limit'>
                <a href='#/phones/{{phone.id}}' class='thumb'><img ng-src='{{phone.imageUrl}}'></a>
                <a href='#/phones/{{phone.id}}'>{{phone.name}}</a>
                <p>{{phone.snippet}}</p>
            </li>
          </ul>
        </div>
    </div>
  </div>

Saya telah menambahkan tag pilih dengan beberapa nilai untuk membatasi jumlah item yang akan ditampilkan. Yang saya inginkan sekarang adalah menambahkan pagination untuk menampilkan 5, 10, dll.

Saya memiliki pengontrol yang berfungsi dengan ini:

function PhoneListCtrl($scope, Phone){
    $scope.phones = Phone.query();
    $scope.orderProp = 'age';
    $scope.limit = 5;
}

Dan saya juga memiliki modul untuk mengambil data dari file json.

angular.module('phonecatServices', ['ngResource']).
    factory('Phone', function($resource){
        return $resource('phones/:phoneId.json', {}, {
            query: {method: 'GET', params:{phoneId:'phones'}, isArray:true}
        });
    });

1
Ketika Anda mengatakan ingin menerapkan halaman berikutnya dan halaman sebelumnya, apakah Anda ingin pagination terjadi murni di sisi klien atau di sisi server. Jika jumlah catatan terlalu tinggi maka Anda harus memilih pagination sisi server. Dalam skenario apa pun Anda perlu mulai mempertahankan "startIndex" - batas hanya akan memberikan jumlah catatan pada halaman, selain dari ini Anda perlu beberapa cara mempertahankan halaman saat ini - ini dapat dilakukan dengan mempertahankan startIndex.
Rutesh Makhijani

Saya tidak memiliki jumlah rekaman yang tinggi. Yang ingin saya lakukan adalah menggunakan controller yang sudah saya miliki (PhoneListCtrl). Saya tidak tahu apakah itu sisi server atau klien. Maaf!
Tomarto

1
@ RuteshMakhijani Saya memiliki persyaratan yang sama dengan jumlah rekaman yang tinggi, tolong jelaskan alasan di balik menggunakan pagination sisi server untuk jumlah rekaman yang tinggi
Dinesh PR

Jawaban:


215

Jika Anda tidak memiliki terlalu banyak data, Anda dapat melakukan pagination dengan hanya menyimpan semua data di browser dan memfilter apa yang terlihat pada waktu tertentu.

Berikut contoh pagination sederhana: http://jsfiddle.net/2ZzZB/56/

Contoh itu ada di daftar biola pada angular.js github wiki, yang seharusnya membantu: https://github.com/angular/angular.js/wiki/JsFiddle-Examples

EDIT: http://jsfiddle.net/2ZzZB/16/ ke http://jsfiddle.net/2ZzZB/56/ (tidak akan menampilkan "1 / 4.5" jika ada 45 hasil)


1
Terima kasih banyak! Persis seperti yang saya cari. Saya melihat contoh itu sebelumnya tetapi tidak berhasil. Sekarang saya perhatikan ada sedikit kesalahan sintaksis. Tanda kurung tidak ada setelah kalimat "untuk".
Tomarto

Saya menambahkan tanda kurung dan memperbaruinya di wiki. Tapi itu seharusnya berhasil tanpa mereka.
Andrew Joslin

1
oh! lupakan. Saya menambahkan if (input?)kondisi sebelum kembali input.slice(start), terima kasih Andy!
zx1986

1
Seperti Bart, saya perlu meneruskan info paging ke fungsi panggilan untuk mendapatkan data pagable - itu serupa tetapi berbeda dan mungkin membantu dalam beberapa kasus. plnkr.co/edit/RcSso3verGtXwToilJ5a
Steve Black

3
Hai, demo ini sangat berguna untuk proyek yang melibatkan saya. Saya perlu menambahkan opsi untuk melihat semua, atau beralih pagination serta menunjukkan setiap halaman. Jadi saya memperpanjang demo. Terima kasih banyak. jsfiddle.net/juanmendez/m4dn2xrv
Juan Mendez

39

Saya baru saja membuat JSFiddle yang menunjukkan pagination + search + order pada setiap kolom menggunakan Build with Twitter Bootstrap code: http://jsfiddle.net/SAWsA/11/


2
Pekerjaan yang mengagumkan. Jadilah baik untuk mengambil satu langkah lebih jauh dan membuat judul kolom dinamis yaitu mendapatkan semua nilai kunci unik dari item json array dan mengikatnya ke ng-repeat bukan pengkodean keras nilai-nilai. Sesuatu seperti apa yang saya lakukan di sini: jsfiddle.net/gavinfoley/t39ZP
GFoley83

memiliki semua kode dalam pengontrol hanya membuatnya kurang dapat digunakan kembali - telerik.com/help/silverlight/… Tampaknya sudut hilang: QueryableDomainServiceCollectionView, VirtualQueryableCollectionView, HierarchicalDataCollectionView
Leblanc Meneses

1
Ini adalah solusi yang sangat hebat, mudah diadaptasi. Menggunakannya pada skenario kompleks di mana jumlah dua elemen yang terikat telah mencapai ribuan, dan itu benar-benar bukan pilihan untuk memperbaiki seluruh kode. Anda harus memperbarui jawabannya dengan beberapa kode yang menjelaskan prinsip-prinsip dasar. Dan mungkin meng-upgrade versi AngularJS dan Bootstrap di biola :)
davidkonrad

15

Saya telah membangun sebuah modul yang membuat pagination di memori sangat sederhana.

Hal ini memungkinkan Anda untuk paginate dengan hanya mengganti ng-repeatdengan dir-paginate, menentukan setiap halaman sebagai filter pipa, dan kemudian menjatuhkan kontrol mana pun Anda seperti dalam bentuk satu direktif,<dir-pagination-controls>

Untuk mengambil contoh asli yang diminta oleh Tomarto, akan terlihat seperti ini:

<ul class='phones'>
    <li class='thumbnail' dir-paginate='phone in phones | filter:searchBar | orderBy:orderProp | limitTo:limit | itemsPerPage: limit'>
            <a href='#/phones/{{phone.id}}' class='thumb'><img ng-src='{{phone.imageUrl}}'></a>
            <a href='#/phones/{{phone.id}}'>{{phone.name}}</a>
            <p>{{phone.snippet}}</p>
    </li>
</ul>

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

Tidak perlu kode pagination khusus di controller Anda. Semuanya ditangani secara internal oleh modul.

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

Sumber: dirPagination of GitHub


JFI: Alih-alih memisahkan dirPagination.tpl.html, kami juga dapat memasukkan kode pagination di dalam <dir-pagination-controls> <ul class = "pagination" ng-if = "1 <pages.length ||! AutoHide">. .. </ul> </dir-pagination-controls>
npcoder

5

Saya tahu utas ini sudah tua sekarang tetapi saya menjawabnya untuk menjaga hal-hal yang sedikit diperbarui.

Dengan Angular 1.4 dan di atas, Anda dapat langsung menggunakan filter limitTo yang selain menerima limitparameter juga menerima beginparameter.

Pemakaian: {{ limitTo_expression | limitTo : limit : begin}}

Jadi sekarang Anda mungkin tidak perlu menggunakan perpustakaan pihak ketiga apa pun untuk mencapai sesuatu seperti pagination. Saya telah membuat biola untuk mengilustrasikan hal yang sama.


Biola yang Anda tautkan tidak benar-benar menggunakan parameter begin.
The Brawny Man

3

Lihat arahan ini: https://github.com/samu/angular-table

Ini mengotomatiskan penyortiran dan pagination banyak dan memberi Anda cukup kebebasan untuk menyesuaikan tabel / daftar Anda seperti yang Anda inginkan.


Pada pandangan pertama ini tampak seperti apa yang saya butuhkan, tetapi saya tidak bisa membuatnya bekerja dengan sumber daya $. Sepertinya selalu menganggap daftar saya kosong di sini: github.com/ssmm/angular-table/blob/master/coffee/ ... ... belum bisa mengetahui alasannya. : /
Mike Desjardins

bagaimana cara menunjukkan Sno di kolom pertama karena saya tidak bisa menggunakan $indexdan array saya tidak mengandung nilai
Dwigh

saya melakukan ini: <td at-sortable at-attribute="index">{{sortedAndPaginatedList.indexOf(item) + 1}}</td>tapi saya tidak tahu apakah itu jalan yang benar
Dwigh

2

Berikut ini adalah kode demo tempat pagination + Filtering dengan AngularJS:

https://codepen.io/lamjaguar/pen/yOrVym

JS:

var app=angular.module('myApp', []);

// alternate - https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination
// alternate - http://fdietz.github.io/recipes-with-angular-js/common-user-interface-patterns/paginating-through-client-side-data.html

app.controller('MyCtrl', ['$scope', '$filter', function ($scope, $filter) {
    $scope.currentPage = 0;
    $scope.pageSize = 10;
    $scope.data = [];
    $scope.q = '';

    $scope.getData = function () {
      // needed for the pagination calc
      // https://docs.angularjs.org/api/ng/filter/filter
      return $filter('filter')($scope.data, $scope.q)
     /* 
       // manual filter
       // if u used this, remove the filter from html, remove above line and replace data with getData()

        var arr = [];
        if($scope.q == '') {
            arr = $scope.data;
        } else {
            for(var ea in $scope.data) {
                if($scope.data[ea].indexOf($scope.q) > -1) {
                    arr.push( $scope.data[ea] );
                }
            }
        }
        return arr;
       */
    }

    $scope.numberOfPages=function(){
        return Math.ceil($scope.getData().length/$scope.pageSize);                
    }

    for (var i=0; i<65; i++) {
        $scope.data.push("Item "+i);
    }
  // A watch to bring us back to the 
  // first pagination after each 
  // filtering
$scope.$watch('q', function(newValue,oldValue){             if(oldValue!=newValue){
      $scope.currentPage = 0;
  }
},true);
}]);

//We already have a limitTo filter built-in to angular,
//let's make a startFrom filter
app.filter('startFrom', function() {
    return function(input, start) {
        start = +start; //parse to int
        return input.slice(start);
    }
});

HTML:

<div ng-app="myApp" ng-controller="MyCtrl">
  <input ng-model="q" id="search" class="form-control" placeholder="Filter text">
  <select ng-model="pageSize" id="pageSize" class="form-control">
        <option value="5">5</option>
        <option value="10">10</option>
        <option value="15">15</option>
        <option value="20">20</option>
     </select>
  <ul>
    <li ng-repeat="item in data | filter:q | startFrom:currentPage*pageSize | limitTo:pageSize">
      {{item}}
    </li>
  </ul>
  <button ng-disabled="currentPage == 0" ng-click="currentPage=currentPage-1">
        Previous
    </button> {{currentPage+1}}/{{numberOfPages()}}
  <button ng-disabled="currentPage >= getData().length/pageSize - 1" ng-click="currentPage=currentPage+1">
        Next
    </button>
</div>
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.