Angularで表を組むのに便利なライブラリと言えば、ngx-datatableです。
https://swimlane.gitbook.io/ngx-datatable/
ngx-datatableでは様々な種類のページング方法に対応しています。
公式の実装サンプルには5つ紹介されていますが、名前からはいまいち違いがわからないように感じたので、分類してみました。
| | 実装サンプル | ページングロジック | 無限スクロール | ページ指定してデータ取得 |
|---|---|---|:-:|:-:|:-:|
| Client-side | https://swimlane.github.io/ngx-datatable/#client-paging | クライアントサイド | × | ○ |
| Server-side | https://swimlane.github.io/ngx-datatable/#server-paging | サーバサイド | × | ○ |
| Scrolling no virtual | https://swimlane.github.io/ngx-datatable/#paging-scrolling-novirtualization | サーバサイド | × | ○ |
| Scrolling server-side | https://swimlane.github.io/ngx-datatable/#server-scrolling | サーバサイド | ○ | × |
| Virtual server-side | https://swimlane.github.io/ngx-datatable/#virtual-paging | サーバサイド | ○ | ○ |
ページングのロジックがクライアントかサーバサイドかの2パターンがありますが、クライアントサイドというのは、全てのデータが入った配列をページごとに区切る処理をクライアントで行う場合です。
datatableのプロパティ早見表
先に結論からで、
無限スクロールありなしとページ指定ありなしの組み合わせパターンに応じた、datatableの@Input
, @Output
の指定の仕方をまとめました。
(ややこしいのでサーバサイドの話のみに絞っています)
@Input @Output
|
説明 | 無限スクロール× ページ指定○ (Server-side、Scrolling no virtual) | 無限スクロール○ ページ指定×(Scrolling server-side) | 無限スクロール○ ページ指定○(Virtual server-side) |
---|---|---|---|---|
[rows] | 表に表示するデータの配列 | 指定ページに属するデータのみ | データの全件の配列 | データの全件の配列 |
[limit] | 1ページあたりの件数 | 指定する | 指定しない | 指定しない |
[externalPaging] | ページングの情報をdatatable外部に持つかどうか | true | false | true |
[count] | 全データ件数 | 指定する | 指定しない | 指定する |
[offset] | ページ番号。0オリジンなので注意。 | 指定する | 指定しない | 指定する |
[virtualization] | スクロールによりページングを行うかどうか | スクロールバーを出したいときは明示的にfalseを指定する必要がある | 指定しない | 指定しない |
(page) | ページを変える際のイベント | 指定する | 指定しない | 指定する |
(scroll) | スクロールした際のイベント | 指定しない | 指定する | 指定しない |
サンプル解説
Client-side
コード:https://github.com/swimlane/ngx-datatable/blob/master/src/app/paging/paging-client.component.ts
[rows]
に全データの配列、[limit]
に1ページあたりの件数を入れるだけです。
Server-side
最も単純なサーバサイドページングの実装です。
コード:https://github.com/swimlane/ngx-datatable/blob/master/src/app/paging/paging-server.component.ts
[rows]
はそのページに属するデータのみの配列になっています。
[externalPaging]
は、サーバサイドでのページングを行う際にtrueにするもので、同時に以下のページングに関連するデータも指定します。
-
[count]
は全データの件数(初期表示時にサーバから取得する必要あり) -
[offset]
はページ番号(※0オリジンです!1ページ目は0) -
[limit]
は1ページあたりの件数
また、もう1つ重要なものとして(page)
があります。これは、ページが変わったときに発火されるイベントで、ページ情報のオブジェクトが$event
オブジェクトとして得られます。(参照:https://swimlane.gitbook.io/ngx-datatable/api/table/outputs#page )
これをもとに、指定したページ番号のデータをサーバ側から取得→得たデータをdatatableの[rows]
に代入、とすることでページめくりができるという仕組みです。
Scrolling no virtual
「Server-side」で、datatableの[scrollbarV]="true"
にしたいけど、無限スクロールページングをしたいわけじゃないんだよな・・・という場合のパターンです。
他の「Server-side」との差は、[virtualization]="false"
が指定されていることです。[virtualization]
はデフォルトがtrueなので、明示的に無限スクロールじゃないと指定する必要があるためかと考えられます。
Scrolling server-side
無限スクロールだってできます。
コード:https://github.com/swimlane/ngx-datatable/blob/master/src/app/paging/scrolling-server.component.ts
スクロールした際に発火するのが、(scroll)
イベントです。ソースコードは長いですが、スクロールの縦方向の差分を見て次のデータを取る必要がある部分に差し掛かっているかをチェックし、指定された件数(limit
)分次のデータを取得→rows
の後ろにくっつけるということをします。
Virtual server-side
「Scrolling server-side」ではスクロールによって次のページのデータを取ってくる、ということしかできないのですが、「Virtual server-side」は無限スクロールかつ特定のページ番号に属するデータの取得ができるサンプルです。
コード:https://github.com/swimlane/ngx-datatable/blob/master/src/app/paging/paging-virtual.component.ts
「Server-side」とほとんど同じにも見えますが、違うポイントとしては「limit」の指定がないことです。
(page)
の処理を見てみます。
ページ番号(page.pageNumber)と1ページあたりの件数(page.pageSize)を指定してサーバサイドからデータを取得→rowsのページ番号に合った位置にデータを挿入 という流れです。
この処理で、重複したデータが2度入ることがないよう、cache
で「○○ページのデータを取得済みか?」管理しています。