使用 n- 重复对列表进行分页

我正在尝试添加页面到我的列表中。我学习了 AngularJS 教程,一个关于智能手机的教程,我试图只显示一定数量的对象。这是我的 html 文件:

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

我已经添加了一个带有一些值的 select 标记,以便限制将要显示的项目的数量。我现在想要的是添加分页以显示下一个5、10等等。

我有一个控制器可以处理这个:

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

我还有一个模块,用于从 json 文件中检索数据。

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

如果您没有太多的数据,您完全可以通过将所有数据存储在浏览器中并过滤在特定时间可见的内容来进行分页。

下面是来自 angular.js Github 维基小提琴列表的一个 简单的分页示例,应该会有帮助:

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


function MyCtrl($scope) {
$scope.currentPage = 0;
$scope.pageSize = 10;
$scope.data = [];
$scope.numberOfPages=function(){
return Math.ceil($scope.data.length/$scope.pageSize);
}
for (var i=0; i<45; i++) {
$scope.data.push("Item "+i);
}
}


//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);
}
});
<div ng-controller="MyCtrl">
<ul>
<li ng-repeat="item in data | 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 >= data.length/pageSize - 1" ng-click="currentPage=currentPage+1">
Next
</button>
</div>

我复制了公认的答案,但是在 HTML 中添加了一些 Bootstrap 类:

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


function MyCtrl($scope) {
$scope.currentPage = 0;
$scope.pageSize = 10;
$scope.data = [];
$scope.numberOfPages=function(){
return Math.ceil($scope.data.length/$scope.pageSize);
}
for (var i=0; i<45; i++) {
$scope.data.push("Item "+i);
}
}


//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 xmlns:ng="http://angularjs.org" ng-app lang="en">
<head>
<meta charset="utf-8">
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/css/bootstrap.no-icons.min.css" rel="stylesheet">
<link href="http://netdna.bootstrapcdn.com/font-awesome/2.0/css/font-awesome.css" rel="stylesheet">
<script src="http://code.angularjs.org/1.1.0/angular.min.js"></script>
</head>
<body>
<script type="text/javascript">
var sortingOrder = 'name';
</script>


<div ng-controller="ctrlRead">
<div class="input-append">
<input type="text" ng-model="query" ng-change="search()" class="input-large search-query" placeholder="Search">
<span class="add-on"><i class="icon-search"></i></span>
</div>
<table class="table table-striped table-condensed table-hover">
<thead>
<tr>
<th class="id">Id&nbsp;<a ng-click="sort_by('id')"><i class="icon-sort"></i></a></th>
<th class="name">Name&nbsp;<a ng-click="sort_by('name')"><i class="icon-sort"></i></a></th>
<th class="description">Description&nbsp;<a ng-click="sort_by('description')"><i class="icon-sort"></i></a></th>
<th class="field3">Field 3&nbsp;<a ng-click="sort_by('field3')"><i class="icon-sort"></i></a></th>
<th class="field4">Field 4&nbsp;<a ng-click="sort_by('field4')"><i class="icon-sort"></i></a></th>
<th class="field5">Field 5&nbsp;<a ng-click="sort_by('field5')"><i class="icon-sort"></i></a></th>
</tr>
</thead>
<tfoot>
<td colspan="6">
<div class="pagination pull-right">
<ul>
<li ng-class="{disabled: currentPage == 0}">
<a href ng-click="prevPage()">« Prev</a>
</li>
<li ng-repeat="n in range(pagedItems.length)"
ng-class="{active: n == currentPage}"
ng-click="setPage()">
<a href ng-bind="n + 1">1</a>
</li>
<li ng-class="{disabled: currentPage == pagedItems.length - 1}">
<a href ng-click="nextPage()">Next »</a>
</li>
</ul>
</div>
</td>
</tfoot>
<tbody>
<tr ng-repeat="item in pagedItems[currentPage] | orderBy:sortingOrder:reverse">
<td>\{\{item.id}}</td>
<td>\{\{item.name}}</td>
<td>\{\{item.description}}</td>
<td>\{\{item.field3}}</td>
<td>\{\{item.field4}}</td>
<td>\{\{item.field5}}</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>

Http://jsfiddle.net/sawsa/11/

看看这个指令: https://github.com/samu/angular-table

它自动化排序和分页很多,并给予您足够的自由来自定义您的表/列表,无论您想要什么。

我已经构建了一个模块,它使得内存分页非常简单。

它允许您通过简单地将 ng-repeat替换为 dir-paginate来进行分页,将每个页面的项目指定为管道过滤器,然后以单个指令 <dir-pagination-controls>的形式随意删除控件

以 Tomarto 最初提出的例子为例,它看起来是这样的:

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

控制器中不需要任何特殊的分页代码,它们都由模块在内部处理。

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

资料来源: GitHub 的分页

下面是一个演示代码,其中有分页 + 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>

我知道这个帖子现在已经过时了,但我还是回复了它,以保持一些更新。

与角度1.4及以上,您可以直接使用 限制过滤器,除了接受 limit参数也接受 begin参数。

用法: \{\{ limitTo_expression | limitTo : limit : begin}}

因此,现在您可能不需要使用任何第三方库来实现分页之类的功能。我创建了一个 小提琴来说明这一点。