メモリ内に約1000アイテムのデータセットがあり、このデータセットのポケットベルを作成しようとしていますが、これを行う方法がわかりません。
カスタムフィルター関数を使用して結果をフィルター処理していますが、これは正常に機能しますが、どういうわけかページ数を取得する必要があります。
手がかりはありますか?
メモリ内に約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
興味があれば、モジュールの設計についてもう少し洞察を加えた短い記事も書いています。
btfordコードを使用して、各列でページネーション+検索+オーダーバイを表示するJSFiddleを作成しました: http://jsfiddle.net/SAWsA/11/
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>
これは、Google 検索結果のようなページネーション ロジックを実装するために Angular サービスとしてラップした純粋な JavaScript ソリューションです。
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="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);
};
});
jQuery Mobile angular アダプターには、基になるページング フィルターがあります。
これを使用するデモ フィドルを次に示します (5 つ以上の項目を追加すると、ページ化されます): http://jsfiddle.net/tigbro/Du2DY/
ソースは次のとおりです: https://github.com/tigbro/jquery-mobile-angular-adapter/blob/master/src/main/webapp/utils/paging.js
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"
このサードパーティのページネーション ライブラリを使用していますが、うまく機能します。ローカル/リモートのデータソースを実行でき、非常に構成可能です。
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>
素晴らしい選択です
実際のページング情報を最小限に抑えながら、大規模なデータセットのページングを支援するディレクティブ。このページング スキームでの結果の「フィルタリング」は、サーバーに大きく依存しています。アイテムのリスト全体をメモリに保持してクライアント側でページングするのではなく、アイテムのアクティブな「ページ」のみを保持したいという中心的な考え方です。
古い質問ですが、私のアプローチは少し異なり、複雑ではないと思うので、これを共有し、私以外の誰かが役立つことを願っています.
ページネーションの簡単で小さな解決策であることがわかったのは、同じスコープ変数を使用するフィルターとディレクティブを組み合わせることです。
これを実装するには、配列にフィルターを追加し、次のようにディレクティブを追加します
<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;
以前のメッセージでは、基本的に自分でページングを構築する方法を推奨していました。あなたが私のようで、完成したディレクティブを好むなら、私は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/
概要:を使用したページネーション
- 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();
}]);