<html>
  <head>
    <link rel="stylesheet" href="./style.css" />
    <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.3/angular.min.js"></script>
    <script src='./people.js'></script>
    <script src="./app.js"></script>
  </head>

  <body ng-app="exampleApplication">
    <div ng-controller="PersonCtrl as personCtrl">
        <div class="table">
         <div class="table-row heading">
               <div class="table-cell heading">Name</div>
               <div class="table-cell heading">Gender</div>
         </div>
         <div ng-repeat="person in personCtrl.people | paginate:personCtrl.currentPageNumber:personCtrl.itemsPerPage" class="table-row">
           <div class="table-cell">{{ person.familyName | uppercase }}, {{ person.givenName }}</div>
           <div class="table-cell center">{{ person.gender == 'M' ? 'Male' : 'Female' }}</div>
         </div>
       </div>
       <div class="table controls">
           <div class="table-row">
             <div class="table-cell left"><a ng-if="personCtrl.currentPageNumber > 1" ng-click="personCtrl.pageDown()"><i class="fa fa-fw fa-lg fa-arrow-circle-left"></i></a></div>
             <div class="table-cell center">
               <div>Page {{ personCtrl.currentPageNumber }} of {{ personCtrl.getNumberOfPages() | number }}</div>    
             </div>
             <div class="table-cell right"><a ng-if="personCtrl.currentPageNumber < personCtrl.getNumberOfPages()" ng-click="personCtrl.pageUp()"><i class="fa fa-fw fa-lg fa-arrow-circle-right"></a></i></div>
           </div>
           
       </div>
    </div>
  </body>

</html>
angular.module('exampleApplication', [])
    .filter('paginate', function(){
        return function(array, pageNumber, itemsPerPage){
            var begin = ((pageNumber - 1) * itemsPerPage);
            var end = begin + itemsPerPage;
            return array.slice(begin, end);
        };
    })
     .controller('PersonCtrl', function($scope) {
       
       this.currentPageNumber = 1;
       this.itemsPerPage = 10;
       this.people = fillArrayWithPeople(new Array(100000));  //100 000 rows.
       
       this.getNumberOfPages = function() {
         var count = this.people.length / this.itemsPerPage;
         if((this.people.length % this.itemsPerPage) > 0) count++;
         return count;
       }
       
       this.pageDown = function()
       {
         if(this.currentPageNumber > 1) this.currentPageNumber--;
       }
       
       this.pageUp = function()
       {
         if(this.currentPageNumber < this.getNumberOfPages()) this.currentPageNumber++;
       }
   });
html {
    background: #E0E0E0;
}

body {
  padding: 50px 50px;
  color: #545454;
  font: 400 16px/1.5 "Calluna Sans","Gill Sans",Calibri,"Trebuchet MS",sans-serif;
  -webkit-font-smoothing: antialiased;
}

div.table {
  display: table;
  width: 400px;
  border: 1px solid #999999;
  border-collapse: collapse;
}

div.table-row {
  display: table-row;
  border: 1px solid #999999;
}

div.table-row.heading {
  text-align: center;
}

div.table-row:nth-child(odd) {
  background-color: #cccccc;
}

div.table-cell {
  display: table-cell;
  padding: 10px 10px;
}

div.table-cell.center {
  text-align: center;
}

div.table-cell.left {
  text-align: left;
}

div.table-cell.right {
  text-align: right;
}

div.table-cell.heading {
  border-left: 1px solid #999999;
  border-bottom: 1px solid #999999;
}

div.controls div.table-cell {
  width: 33%;
}

function fillArrayWithPeople(destination)
{
  var maleNames = [ 'Max','Bailey','Charlie','Buddy','Rocky','Jake','Jack','Toby','Cody','Buster','Duke','Cooper','Riley','Harley','Bear','Tucker','Murphy','Lucky','Oliver','Sam','Oscar','Teddy','Winston','Sammy','Rusty','Shadow','Gizmo','Bentley','Zeus','Jackson','Baxter','Bandit','Gus','Samson','Milo','Rudy','Louie','Hunter','Casey','Rocco','Sparky','Joey','Bruno','Beau','Dakota','Maximus','Romeo','Boomer','Luke','Henry'];
  var femaleNames = [ 'Bella','Lucy','Molly','Daisy','Maggie','Sophie','Sadie','Chloe','Bailey','Lola','Zoe','Abby','Ginger','Roxy','Gracie','Coco','Sasha','Lily','Angel','Princess','Emma','Annie','Rosie','Ruby','Lady','Missy','Lilly','Mia','Katie','Zoey','Madison','Stella','Penny','Belle','Casey','Samantha','Holly','Lexi','Lulu','Brandy','Jasmine','Shelby','Sandy','Roxie','Pepper','Heidi','Luna','Dixie','Honey','Dakota'];
  var familyNames = ['Adams','Allen','Anderson','Bailey','Baker','Barnes','Bell','Bennett','Brooks','Brown','Butler','Campbell','Carter','Clark','Collins','Cook','Cooper','Cox','Cruz','Davis','Díaz','Edwards','Evans','Fisher','Flores','Foster','García','González','Gray','Green','Gutiérrez','Gómez','Hall','Harris','Hernández','Hill','Howard','Hughes','Jackson','James','Jenkins','Johnson','Jones','Kelly','King','Lee','Lewis','Long','López','Martin','Martínez','Miller','Mitchell','Moore','Morales','Morgan','Morris','Murphy','Myers','Nelson','Nguyen','Ortiz','Parker','Perry','Peterson','Phillips','Powell','Price','Pérez','Ramírez','Reed','Reyes','Richardson','Rivera','Roberts','Robinson','Rodríguez','Rogers','Ross','Russell','Sanders','Scott','Smith','Stewart','Sullivan','Sánchez','Taylor','Thomas','Thompson','Torres','Turner','Walker','Ward','Watson','White','Williams','Wilson','Wood','Wright','Young'];
  
  for(var i = 0; i < destination.length; i++)
  {
    var gender = Math.random() > 0.5 ? 'F' : 'M';
    destination[i] = {
      gender : gender,
      givenName : gender == 'F' ? femaleNames[Math.floor(Math.random()*femaleNames.length)] : maleNames[Math.floor(Math.random()*maleNames.length)],
      familyName : familyNames[Math.floor(Math.random()*familyNames.length)]
    }
  }
  return destination;
}

#AngularJS Pagination with a Filter
This plunk demonstrates a trivial filter that can be used to paginate collections/arrays of data in AngularJS.

While using a filter may not be an optimal solution in cases where the paginated data is decorated heavily with Angular functionality, this solution performs well, even on large sets of data.