メモリ内に約1000項目のデータセットがあり、このデータセット用のポケットベルを作成しようとしていますが、これを行う方法がわかりません。
私は結果をフィルタリングするためにカスタムフィルタ関数を使っています、そしてそれはうまくいきますが、どういうわけか私はページ数を取り出す必要があります。
何か手がかりはありますか?
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);
});
});
参照用に 実用的なプランカーを作成しました 。
私は最近Built with Angularサイトのページングを実装しました。あなたはソースをチェックアウトするちゃん: https://github.com/angular/builtwith.angularjs.org
ページを区切るためにフィルタを使用しないでください。項目をコントローラ内のページに分割する必要があります。
私は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/
Scotty.NETの plunkr http://plnkr.co/edit/FUeWwDu0XzO51lyLAEIA?p = preview を更新して、新しいバージョンのangle、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>
これは、Googleの検索結果のようにページネーションロジックを実装するためのAngularサービスとしてまとめた純粋なJavaScriptソリューションです。
CodePenの作業デモは http://codepen.io/cornflourblue/pen/KVeaQL/ にあります。
このブログ記事 の詳細と説明
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" >
あなたのangleJsで:
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
も受け入れます
docs :から
{{limitTo_expression | limitTo:limit:begin}}
begin(オプション)文字列|番号
制限を始めるインデックス。負のインデックスとして、beginは入力の末尾からのオフセットを示します。デフォルトは0です。
したがって、新しいディレクティブを作成する必要はありません 、この引数は、ページ区切りのオフセットを設定するために使用できます。
ng-repeat="item in vm.items| limitTo: vm.itemsPerPage: (vm.currentPage-1)*vm.itemsPerPage"
ng-repeatページネーション
<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;
_ demo _ このプランカーの完全な解決策を見る
私の例があります。リストコントローラの中央にある選択されたボタン。設定>>>
$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);
});
そして私のブートストラップ観
<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 >
それは便利です
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
before にフィルタを適用してください。
<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>
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();
ページネーションのその他のオプションについてはこちらを参照してください。 ブートストラップUIページネーション指示
概要 : を使用してページ付け
- 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();
}]);
私はコメントして欲しいのですが、私はこれをここに残しておく必要があります。
Scotty.NETの答えとそれ以降のバージョンに対するuser2176745のやり直しはどちらも素晴らしいことですが、どちらも私のバージョンのAngularJS(v1.3.15)が壊れていることを見逃しています。
私は$ scope.makeTodosで定義されていません。
そのため、この関数に置き換えることで、より最近のAngularバージョン用に修正されます。
$scope.makeTodos = function() {
var i;
$scope.todos = [];
for (i=1;i<=1000;i++) {
$scope.todos.Push({ text:'todo '+i, done:false});
}
};