How to do paging in AngularJS?

后端 未结 21 1850
轮回少年
轮回少年 2020-11-22 07:17

I have a dataset of about 1000 items in-memory and am attempting to create a pager for this dataset, but I\'m not sure on how to do this.

I\'m using a custom filter

相关标签:
21条回答
  • 2020-11-22 07:44

    Since Angular 1.4, the limitTo filter also accepts a second optional argument begin

    From the docs:

    {{ limitTo_expression | limitTo : limit : begin}}

    begin (optional) string|number
    Index at which to begin limitation. As a negative index, begin indicates an offset from the end of input. Defaults to 0.

    So you don't need to create a new directive, This argument can be used to set the offset of the pagination

    ng-repeat="item in vm.items| limitTo: vm.itemsPerPage: (vm.currentPage-1)*vm.itemsPerPage" 
    
    0 讨论(0)
  • 2020-11-22 07:45

    You can easily do this using Bootstrap UI directive.

    This answer is a modification of the answer given by @Scotty.NET, I have changed the code because <pagination> directive is deprecated now.

    Following code generates the 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>
    

    To make it functional, use this in your controller:

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

    Refer to this for more options of pagination: Bootstrap UI Pagination Directive

    0 讨论(0)
  • 2020-11-22 07:46

    Angular UI Bootstrap - Pagination Directive

    Check out UI Bootstrap's pagination directive. I ended up using it rather than what is posted here as it has enough features for my current use and has a thorough test spec to accompany it.

    View

    <!-- table here -->
    
    <pagination 
      ng-model="currentPage"
      total-items="todos.length"
      max-size="maxSize"  
      boundary-links="true">
    </pagination>
    
    <!-- items/page select here if you like -->
    

    Controller

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

    I have made a working plunker for reference.


    Legacy Version:

    View

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

    Controller

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

    I have made a working plunker for reference.

    0 讨论(0)
  • 2020-11-22 07:46

    Old question but since I think my approach is a bit different and less complex I will share this and hope that someone besides me find it useful.

    What I found to be an easy and small solution to pagination is to combine a directive with a filter which uses the same scope variables.

    To implement this you add the filter on the array and add the directiv like this

    <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 and p_Step are scope variables which can be customized in the scope else the default value of the p_Size is 5 and p_Step is 1.

    When a step is change in the pagination the p_Step is updated and will trigger a new filtering by cust_pagination filter. The cust_pagination filter then slices the array depending on the p_Step value like below and only return the active records selected in the pagination section

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

    DEMO View the complete solution in this plunker

    0 讨论(0)
  • 2020-11-22 07:47

    I would like to add my solution that works with ngRepeat and filters that you use with it without using a $watch or a sliced array.

    Your filter results will be paginated!

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

    In the HTML make sure that you apply your filters to the ngRepeat before the pagination filter.

    <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>
    
    0 讨论(0)
  • 2020-11-22 07:50

    For anyone who find it difficult like me to create a paginator for a table I post this. So, in your view :

              <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 your 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);
                  };
                });     
    
    0 讨论(0)
提交回复
热议问题