前回はListViewを使って要素を繰り返す処理について説明しました。Wicketでは繰り返しは
今回はWebアプリケーションには必須の項目である
リンクを生成する
twitter.
リスト1 お気に入りリンクとリプライリンク
<span class="actions">
<a wicket:id="favLink" class="fav" href="#"><span wicket:id="favName">fav</span></a>
<a wicket:id="replyLink" class="reply" href="#">reply</a>
</span>
お気に入りリンクにはfavLink,
HTMLリンクにWicketのLinkコンポーネントを適用することで,
LinkコンポーネントはHTMLの<a>タグはもちろん,
いずれにせよ,
Buttonコンポーネントをすでに見ているために当たり前のように見えることでしょう。しかし,
Wicketでは,
リスト2 リプライリンクの実装
final Status status = item.getModelObject();
(中略)
item.add(new Link<Void>("replyLink") {
@Override
public void onClick() {
String targetScreenName = status.getUser().getScreenName();
form.insertText("@" + targetScreenName + " ");
}
});
このプログラムはreplyLinkがクリックされた時の動作をプログラムしています。onClick()内で使用しているstatusオブジェクトは,
ここでは,
このformオブジェクトは,
このように機能毎にクラスを分けていくのは,
ListItemの再生成を止める
WicketのListViewは,
ユーザのクリックやサブミットを処理したあと別のページに遷移しなかった場合,
ところが,
そのための重要な処理が,
リスト3 ListItemの再生成を抑止する
timeline.setReuseItems(true);
ListViewのsetReuseItems()にtrueを渡すことで,
逆に,
setReuseItems(true)を呼び出したあとに表を再生成させるには,
状況により表示を切り替える
お気に入り登録リンクも,
リスト4 お気に入りリンクの実装
final Label favName = new Label("favName", new AbstractReadOnlyModel<String>() {
@Override
public String getObject() {
return status.isFavorited() ? "unfav" : "fav";
}
});
Link<Void> favLink = new Link<Void>("favLink") {
@Override
public void onClick() {
try {
Twitter twitterSession = AppSession.get().getTwitterSession();
if(status.isFavorited()) {
twitterSession.destroyFavorite(status.getId());
info(getString("favorateRemoved"));
} else {
twitterSession.createFavorite(status.getId());
info(getString("favorateRegistered"));
}
} catch (TwitterException ex) {
String message = getString("catNotCreateFavorite") + ": " + ex.getStatusCode();
error(message);
LOGGER.error(message, ex);
}
}
};
item.add(favLink);
favLink.add(favName);
表示の切り替えは,
Wicketはプッシュではなくプルを基本としているフレームワークであることを思い出してください。状況に応じて表示する文字列をラベルに設定するのではなく、ラベルのモデル自体が状況を判断して、表示すべき文字列を返すのです。プルを使うと、手続きの流れではなくオブジェクトを組み合わせてアプリケーションを作る、というWicketらしいオブジェクト指向アプリケーションになります。
favNameラベルは行を表すitemオブジェクトではなく,
favLinkコンポーネントの実装はほかに比べると若干長いですが,
populateItem()メソッド内の実装方法は,