How to do paging in AngularJS?

后端 未结 21 1904
轮回少年
轮回少年 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:55

    This is a pure javascript solution that I've wrapped as an Angular service to implement pagination logic like in google search results.

    Working demo on CodePen at http://codepen.io/cornflourblue/pen/KVeaQL/

    Details and explanation at this blog post

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

    Angular-Paging

    is a wonderful choice

    A directive to aid in paging large datasets while requiring the bare minimum of actual paging information. We are very dependant on the server for "filtering" results in this paging scheme. The central idea being we only want to hold the active "page" of items - rather than holding the entire list of items in memory and paging on the client-side.

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

    I've extracted the relevant bits here. This is a 'no frills' tabular pager, so sorting or filtering is not included. Feel free to change/add as needed:

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

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

    ng-repeat pagination

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

    I wish I could comment, but I'll just have to leave this here:

    Scotty.NET's answer and user2176745's redo for later versions are both great, but they both miss something that my version of AngularJS (v1.3.15) breaks on:

    i is not defined in $scope.makeTodos.

    As such, replacing with this function fixes it for more recent angular versions.

    $scope.makeTodos = function() {
        var i;
        $scope.todos = [];
        for (i=1;i<=1000;i++) {
            $scope.todos.push({ text:'todo '+i, done:false});
        }
    };
    
    0 讨论(0)
  • 2020-11-22 08:04

    Previous messages recommended basically how to build a paging by yourself. If you are like me, and prefer a finished directive, I just found a great one called ngTable. It supports sorting, filtering and pagination.

    It is a very clean solution, all you need in your view:

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

    And in 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 to GitHub: https://github.com/esvit/ng-table/

    0 讨论(0)
提交回复
热议问题