PageableListViewとページネーション
続いて、データを一覧表示する処理についてです。多数のデータがあるとき、そこから1つずつデータを取り出して繰り返し表示するためのコンポーネントがWicketには用意されています。それは「ListView」というものです。これは次のような形で作成します。
new ListView<String>( タグのID, データ );
第2引数には、Listなどのコレクションを用意します。ListViewは、ここから順にデータのオブジェクトを取り出し、それを指定されたタグに設定してデータの表示を行います。各項目の表示は、ListViewに用意されるpopulateItemというメソッドで作成します。
protected void populateItem(ListItem item) {
……ここに処理を用意する……
}
データから取り出された値は、ListItemというクラスのインスタンスとして引数に渡されます。これを利用し、必要に応じてコンポーネントをaddするなどして表示を作成していきます。
今回は、このListViewを更に拡張した「PageableListView」というコンポーネントを使っています。これはページネーション機能を備えたListViewです。
new PageableListView<String>( タグのID, データ, ページあたりの表示数 );
インスタンスを作成する際に、このように引数を指定します。ここで作成したサンプルのPageableListViewの作成部分を見てみると、無名クラスを利用してpopulateItemメソッドを実装し、次のようにインスタンスを用意しています。
list = new PageableListView<String>("list",datalist,5){
private static final long serialVersionUID = 1L;
@Override
protected void populateItem(ListItem<String> item) {
String s = item.getModelObject();
item.add(new Label("comment",s));
}
};
引数には、datalistというArrayListインスタンスを渡し、表示するIDには"list"を指定しています。そして、populateItemでは、ListItemからgetModelObjectでオブジェクトを取り出し、それをnew Labelしたものをitem.addしています。
では、実際にどのように表示が作成されるのでしょうか。HTMLテンプレートでは、次のようにタグが用意されています。
<div wicket:id="list">
<hr />
<span wicket:id="comment"></span>
</div>
PageableListViewに"list"が設定され、populateItemメソッドでnew Label("comment",s)をaddしています。これにより、<span wicket:id="comment">にpopulateItemで作成されたLabelが設定されます。これにより、HTMLの出力は、このように繰り返し出力されます。
<div wicket:id="list">
<hr />
<span wicket:id="comment">1つ目のデータ</span>
<hr />
<span wicket:id="comment">2つ目のデータ</span>
<hr />
<span wicket:id="comment">3つ目のデータ</span>
……以下略……
</div>
なお、ここではPageableListViewを使いページ分け表示をしましたが、ページネーションのために必要な処理は実は特にありません。ただPageableListViewを作りaddするだけなのです。ただし、これだけではページ移動のための操作が行えないので、次のようにしてページ移動のインターフェースを追加しています。
this.add(new PagingNavigator("navigate", list));
PagingNavigatorは、PageableListViewのページ移動インターフェースを提供するコンポーネントです。これをaddすると、ページの移動に関する標準的なリンク(最初のページ、前のページ、現在開いているページ前後の最大10ページ分の番号、次のページ、最後のページ)が自動的に生成されます。
PageableListViewとPagingNavigatorを使ってみると、一般にひどく面倒くさい印象のあるページネーションがあっさり実現できてしまうことに驚きます。ListViewをPageableListViewだけ、インターフェースもPagingNavigatorをaddするだけで簡単に作成できてしまうからです。
Linkとページ移動
続いて、<a>タグとページ移動についてです。<a>タグによるリンクは、Wicketでは「Link」というコンポーネントとして用意されています。これは、クリックしたときのイベント処理を行う「onClick」というメソッドを持っています。これにより、クリック時に必要な処理を実行させることができます。ここでは次のような形でコンポーネントを作成しています。
Link<String> link = new Link<String>("link"){
private static final long serialVersionUID = 1L;
@Override
public void onClick() {
this.setResponsePage(OtherPage.class);
}
};
リンクをクリックすると、OtherPageというWebPageに移動するようにしています。ページの移動は、WebPageクラスにある「setResponsePage」というメソッドを呼び出します。これで引数にWebPageクラス(およびそのサブクラス)を指定すると、そのWebPageの表示に移動します。
Wicketでは、「ページ遷移」という考え方を頭から取り除く必要があります。通常のWebアプリケーションでは、表示はそれぞれHTMLのファイルとして用意され、そのファイルのアドレスにアクセスして表示されます。しかし、Wicketでは、用意されるのはあくまで「テンプレート」です。Wicketが指定されたページのテンプレートを読み込み、それをレンダリングしてクライアントに送っているのです。表示されるページが移動したり別のアドレスに遷移しているわけではなく、「使用するWebPageクラスが変更される」のです。WebPageが変わることにより、ロードされるテンプレートも変わり、結果として別の表示に変わります。しかし、内部で行っているのは「ページの移動」ではなく、あくまで「使用するクラスの変更」に過ぎないのです。
