回答:
UI Bootstrapのページネーションディレクティブを確認してください。私の現在の使用に十分な機能があり、それに伴う十分なテスト仕様があるため、ここに投稿されたものではなく、結局使用しました。
<!-- table here -->
<pagination
ng-model="currentPage"
total-items="todos.length"
max-size="maxSize"
boundary-links="true">
</pagination>
<!-- items/page select here if you like -->
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);
});
});
参考のために私は実用的なプランカーを作りました。
<!-- 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 -->
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);
});
});
参考のために私は実用的なプランカーを作りました。
pagination
要素に設定する必要があるプロパティです。
最近、Built with Angularサイトにページングを実装しました。あなたはソースをチェックアウトすることができます:https : //github.com/angular/builtwith.angularjs.org
フィルターを使用してページを分離することは避けます。アイテムをコントローラー内のページに分割する必要があります。
Use your downvotes whenever you encounter an egregiously sloppy, no-effort-expended post, or an answer that is clearly and perhaps dangerously incorrect.
私はAngularで何度もページ分割を実装する必要がありましたが、単純化できると感じるものには常に少し苦労しました。ここや他の場所で提示されているアイデアのいくつかを使用して、ページ付けを次のように単純にするページ付けモジュールを作成しました。
<ul>
<li dir-paginate="item in items | itemsPerPage: 10">{{ item }}</li>
</ul>
// then somewhere else on the page ....
<dir-pagination-controls></dir-pagination-controls>
それでおしまい。次の機能があります。
items
をページネーションリンクに関連付ける。ng-repeat
ためng-repeat
、フィルタリング、順序付けなど、で有効に使用できる任意の式を使用できます。pagination-controls
機能しpaginate
ます。ディレクティブは、ディレクティブが呼び出されるコンテキストについて何も知る必要はありません。「プラグアンドプレイ」ソリューションを探している人にとって、これは便利だと思います。
このコードはGitHubから入手でき、非常に優れた一連のテストが含まれています。
https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination
興味があれば、モジュールのデザインについてもう少し洞察した短い記事も書きました:http : //www.michaelbromley.co.uk/blog/108/paginate-almost-anything-in-angularjs/
btfordコードを使用して、各列にページネーション+検索+順序を表示するJSFiddleを作成しました:http ://jsfiddle.net/SAWsA/11/
new_sorting_order
ますnewSortingOrder
。修正してを追加すると@scope.search();
、期待どおりに並べ替えられ、並べ替えアイコンも更新されます。(ブラウザーのデバッグコンソールを開いた状態でフィドルを実行します(Chrome、F12、コンソールタブ)。これは明らかです)。
Scotty.NETの plunkr を更新しましたhttp://plnkr.co/edit/FUeWwDu0XzO51lyLAEIA?p=preview、angular、angular-ui、およびブートストラップの新しいバージョンを使用するようにしました。
コントローラ
var todos = angular.module('todos', ['ui.bootstrap']);
todos.controller('TodoController', function($scope) {
$scope.filteredTodos = [];
$scope.itemsPerPage = 30;
$scope.currentPage = 4;
$scope.makeTodos = function() {
$scope.todos = [];
for (i=1;i<=1000;i++) {
$scope.todos.push({ text:'todo '+i, done:false});
}
};
$scope.figureOutTodosToDisplay = function() {
var begin = (($scope.currentPage - 1) * $scope.itemsPerPage);
var end = begin + $scope.itemsPerPage;
$scope.filteredTodos = $scope.todos.slice(begin, end);
};
$scope.makeTodos();
$scope.figureOutTodosToDisplay();
$scope.pageChanged = function() {
$scope.figureOutTodosToDisplay();
};
});
ブートストラップUIコンポーネント
<pagination boundary-links="true"
max-size="3"
items-per-page="itemsPerPage"
total-items="todos.length"
ng-model="currentPage"
ng-change="pageChanged()"></pagination>
これは純粋なjavascriptソリューションであり、Googleの検索結果のようにページ分割ロジックを実装するためにAngularサービスとしてラップしました。
http://codepen.io/cornflourblue/pen/KVeaQL/にあるCodePenの作業デモ
このブログ投稿の詳細と説明
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
};
}
}
ここで関連するビットを抽出しました。これは「飾り気のない」表形式ページャーなので、並べ替えやフィルタリングは含まれていません。必要に応じて自由に変更/追加してください。
//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()">«</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()">»</a>
</td>
</tr>
</tfoot>
</table>
以下のソリューションは非常に簡単です。
<pagination
total-items="totalItems"
items-per-page= "itemsPerPage"
ng-model="currentPage"
class="pagination-sm">
</pagination>
<tr ng-repeat="country in countries.slice((currentPage -1) * itemsPerPage, currentPage * itemsPerPage) ">
jQuery Mobile角度アダプターには、ベースとなるページングフィルターがあります。
これを使用するデモフィドルは次のとおりです(5つ以上のアイテムを追加するとページングされます):http : //jsfiddle.net/tigbro/Du2DY/
これがソースです:https : //github.com/tigbro/jquery-mobile-angular-adapter/blob/master/src/main/webapp/utils/paging.js
私のようにテーブルのページネーションを作成するのが難しいと思う人のために、これを投稿します。だから、あなたの見解では:
<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" >
あなたの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);
};
});
私はこのサードパーティのページ付けライブラリを使用しており、うまく動作します。ローカル/リモートデータソースを行うことができ、非常に構成可能です。
https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination
<dir-pagination-controls
[max-size=""]
[direction-links=""]
[boundary-links=""]
[on-page-change=""]
[pagination-id=""]
[template-url=""]
[auto-hide=""]>
</dir-pagination-controls>
Angular 1.4以降、limitTo
フィルターは2番目のオプションの引数も受け入れますbegin
ドキュメントから:
{{limitTo_expression | limitTo:limit:begin}}
begin(オプション)string | number
制限を開始するインデックス。負のインデックスとして、beginは入力の終わりからのオフセットを示します。デフォルトは0です。
そのため、新しいディレクティブを作成する必要はありません。この引数を使用して、ページネーションのオフセットを設定できます
ng-repeat="item in vm.items| limitTo: vm.itemsPerPage: (vm.currentPage-1)*vm.itemsPerPage"
これは、Bootstrap UIディレクティブを使用して簡単に行うことができます。
この回答は、@ Scotty.NETによって提供された回答を変更したものです<pagination>
。現在ディレクティブが廃止されているため、コードを変更しました。
次のコードはページネーションを生成します:
<ul uib-pagination
boundary-links="true"
total-items="totalItems"
items-per-page="itemsPerPage"
ng-model="currentPage"
ng-change="pageChanged()"
class="pagination"
previous-text="‹"
next-text="›"
first-text="«"
last-text="»">
</ul>
これを機能させるには、これをコントローラーで使用します。
$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();
ページネーションのその他のオプションについては、これを参照してください:Bootstrap UI Pagination Directive
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>
以前のメッセージでは、基本的に自分でページングを作成する方法を推奨していました。あなたが私のようなもので、完成したディレクティブを好むなら、私はngTableと呼ばれる素晴らしいものを見つけました。並べ替え、フィルタリング、ページネーションをサポートしています。
これは非常にクリーンなソリューションであり、必要なものは次のとおりです。
<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>
そしてコントローラーで:
$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));
}
});
GitHubへのリンク:https : //github.com/esvit/ng-table/
素晴らしい選択です
実際のページング情報を最小限に抑えながら、大規模なデータセットのページングを支援するディレクティブ。このページングスキームでの "フィルタリング"の結果は、サーバーに大きく依存しています。中心的な考え方は、アイテムのリスト全体をメモリに保持してクライアント側でページングするのではなく、アイテムのアクティブな「ページ」だけを保持することです。
古い質問ですが、私のアプローチは少し異なり、それほど複雑ではないと思いますので、これを共有し、私以外の誰かがそれが役立つことを願っています。
簡単で小さな解決策であることがわかったものページネーションのは、ディレクティブと同じスコープ変数を使用するフィルターを組み合わせることです。
これを実装するには、配列にフィルターを追加し、次のようにディレクティブを追加します
<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とp_Stepはスコープ変数であり、スコープでカスタマイズできます。それ以外の場合、p_Sizeのデフォルト値は5で、p_Stepは1です。
ページ付けのステップが変更されると、p_Stepが更新され、cust_paginationフィルターによる新しいフィルタリングがトリガーされます。次に、cust_paginationフィルターは、以下のようにp_Step値に応じて配列をスライスし、ページネーションセクションで選択されたアクティブなレコードのみを返します
var startIndex = nStep * nPageSize;
var endIndex = startIndex + nPageSize;
var arr = items.slice(startIndex, endIndex);
return arr;
私の例があります。リストコントローラの中央にある選択されたボタン。設定>>>
$scope.pagination = {total: null, pages: [], config: {count: 10, page: 1, size: 7}};
ページネーションのロジック:
/*
Pagination
*/
$scope.$watch('pagination.total', function (total) {
if(!total || total <= $scope.pagination.config.count) return;
_setPaginationPages(total);
});
function _setPaginationPages(total) {
var totalPages = Math.ceil(total / $scope.pagination.config.count);
var pages = [];
var start = $scope.pagination.config.page - Math.floor($scope.pagination.config.size/2);
var finish = null;
if((start + $scope.pagination.config.size - 1) > totalPages){
start = totalPages - $scope.pagination.config.size;
}
if(start <= 0) {
start = 1;
}
finish = start + $scope.pagination.config.size - 1;
if(finish > totalPages){
finish = totalPages;
}
for (var i = start; i <= finish; i++) {
pages.push(i);
}
$scope.pagination.pages = pages;
}
$scope.$watch("pagination.config.page", function(page){
_setPaginationPages($scope.pagination.total);
_getRespondents($scope.pagination.config);
});
そしてbootstapに関する私の見解
<ul ng-class="{hidden: pagination.total == 0}" class="pagination">
<li ng-click="pagination.config.page = pagination.config.page - 1"
ng-class="{disabled: pagination.config.page == 1}" ><a href="#">«</a></li>
<li ng-repeat="p in pagination.pages"
ng-click="pagination.config.page = p"
ng-class="{active: p == pagination.config.page}"><a href="#">{{p}}</a></li>
<li ng-click="pagination.config.page = pagination.config.page + 1"
ng-class="{disabled: pagination.config.page == pagination.pages.length}"><a href="#">»</a></li>
</ul >
それは便利です
コメントしたいのですが、ここに残しておくだけです。
Scotty.NETの回答とそれ以降のバージョンのuser2176745のやり直しはどちらも素晴らしいですが、どちらも私のバージョンのAngularJS(v1.3.15)が壊れているものを見逃しています。
私は$ scope.makeTodosで定義されていません。
そのため、この関数で置き換えると、最新の角度バージョンで修正されます。
$scope.makeTodos = function() {
var i;
$scope.todos = [];
for (i=1;i<=1000;i++) {
$scope.todos.push({ text:'todo '+i, done:false});
}
};
概要:ページネーション
- ng-repeat
- uib-pagination
表示:
<div class="row">
<div class="col-lg-12">
<table class="table">
<thead style="background-color: #eee">
<tr>
<td>Dispature</td>
<td>Service</td>
<td>Host</td>
<td>Value</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in app.metricsList">
<td>{{x.dispature}}</td>
<td>{{x.service}}</td>
<td>{{x.host}}</td>
<td>{{x.value}}</td>
</tr>
</tbody>
</table>
<div align="center">
<uib-pagination items-per-page="app.itemPerPage" num-pages="numPages"
total-items="app.totalItems" boundary-link-numbers="true"
ng-model="app.currentPage" rotate="false" max-size="app.maxSize"
class="pagination-sm" boundary-links="true"
ng-click="app.getPagableRecords()"></uib-pagination>
<div style="float: right; margin: 15px">
<pre>Page: {{app.currentPage}} / {{numPages}}</pre>
</div>
</div>
</div>
</div>
JSコントローラ:
app.controller('AllEntryCtrl',['$scope','$http','$timeout','$rootScope', function($scope,$http,$timeout,$rootScope){
var app = this;
app.currentPage = 1;
app.maxSize = 5;
app.itemPerPage = 5;
app.totalItems = 0;
app.countRecords = function() {
$http.get("countRecord")
.success(function(data,status,headers,config){
app.totalItems = data;
})
.error(function(data,status,header,config){
console.log(data);
});
};
app.getPagableRecords = function() {
var param = {
page : app.currentPage,
size : app.itemPerPage
};
$http.get("allRecordPagination",{params : param})
.success(function(data,status,headers,config){
app.metricsList = data.content;
})
.error(function(data,status,header,config){
console.log(data);
});
};
app.countRecords();
app.getPagableRecords();
}]);
またはスライスされた配列ngRepeat
を使用せずに使用するフィルターと一緒に機能する私のソリューションを追加したいと思います$watch
。
フィルター結果にページ番号が付けられます!
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;
};
}]);
HTMLでは、ページネーションフィルターのngRepeat
前にフィルターを適用してください。
<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="‹"
data-next-text="›"
data-first-text="«"
data-last-text="»">
</ul>