Wicketで始めるオブジェクト指向ウェブ開発

第8回 組み込みAjax機能で動的に変化するページを実現する

この記事を読むのに必要な時間:およそ 6 分

今回のテーマは,Wicketの組み込みAjax機能を使ってページ全体のリロードを無くすことです。最近のアプリケーションでは,JavaScriptおよびAjaxを使ってページを動的に作り替えることで,ページ全体のリロードを減らす方向にあります。Ajaxなしにアプリケーションを作れない時代になったと言えるでしょう。組み込みAjax機能はそのような動的なページ部分更新をWicket上で実現するためのものです。

組み込みAjax機能の位置づけ

あらかじめ注意しておくと,WicketはJavaScriptフレームワークでもありませんし,Ajax開発のためのフレームワークではありません。Ajaxだけに注目すると,組み込みAjaxの機能は不十分に見えることでしょう。実際,筆者はそういう指摘を受けたこともあります。JavaScript開発のための機能をWicketに求めるのは間違いです。JavaScriptの開発は,あなたのお気に入りのJavaScript用フレームワークを使って行うほうがずっと快適なはずです。WicketはJavaを使ってアプリケーションを構築するフレームワークです。今回紹介する組み込みAjax機能も,あくまでJavaからプログラムできる機能として提供されています。

WicketはJavaScript言語を使った開発のサポートは行いませんが,一方で,開発したJavaScriptソースファイルをコンポーネント内に閉じ込めるための機能は提供します。この機能を使って,コンポーネント使用者がJavaScriptの詳細を知ることなく使える「Wicketコンポーネント」を作ることができます。Wicketが提供するのは,コンポーネントの機能を実装するためにJavaScriptプログラムを利用するための「仕組み」なのです。

Wicketではページを部分的に更新するのは,特別なJavaScript操作を必要とする「つけたし」ではなく,フレームワーク自体に組み込まれた機能の1つです。その機能を実現するために裏ではAjaxを使っている,と考えると,組み込みAjax機能の位置づけが分かりやすいでしょう。今回の記事を読む際にも,JavaScriptのことは一旦忘れ,新しく紹介するWicketの機能を知るつもりで読むのが良いでしょう。

ページの部分更新を行う

Wicketでページの部分更新を行うには,AjaxRequestTargetオブジェクトが必要となります。AjaxRequestTargetオブジェクトはプログラマが自分で用意するものではなく,Wicketにより提供されるオブジェクトです。Wicketの提供するコンポーネントのうち,クラス名の先頭がAjaxで始まるコンポーネントがAjaxRequestTargetに対応しています。

例えば,ボタンをクリックした結果としてページの一部分だけを更新したい場合には,Linkコンポーネントの代わりにAjaxLinkコンポーネントを使います。LinkとAjaxLinkの使い方はほぼ同じで,どちらもユーザのクリックを検知すると自身のonClick()メソッドを呼び出します。ただし,onClick()にAjaxRequestTargetオブジェクトが渡されるかどうかだけが異なります。

リスト1 AjaxLinkのonClick()メソッド

new AjaxLink("link") {
  @Override
  public void onClick(AjaxRequestTarget target) {
    //ここにクリック時の処理を書く
  }
}

上記プログラムのとおり,変わったところはAjaxRequestTargetを引数として受け取っていることだけです。WicketがAjaxRequestTargetオブジェクトを作成して,onClick()に渡してくれます。

Linkコンポーネントでは,onClick()内部でモデルを適切に変更しさえすれば,ページ全体が再描画されることで,最新の状態が表示に反映されました。しかし,AjaxLinkでは何もしなければページは一切変化しません。変化させたい場所をWicketに伝えなくてはならないのです。

Wicketに変更箇所を指定する方法は,AjaxRequestTargetオブジェクトに再描画したいコンポーネントをaddComponent()メソッドでセットするだけです。

リスト2 リンクがクリックされたらlabelだけを更新する

final Label label = new Label("myLabel");
add(label);
(中略)
new AjaxLink("link") {
  @Override
  public void onClick(AjaxRequestTarget target) {
    target.addComponent(label);
  }
}

このプログラムでは,AjaxLinkをクリックするとaddComponent()メソッドでlabelコンポーネントをAjaxRequestTargetに登録しています。これだけで,Wicketが裏側でAjaxを利用して,labelコンポーネントが適用されているタグ部分だけを更新します。addComponent()は何度でも呼ぶことができます。Wicketコンポーネントを適用しているタグであれば,どこでも同じ方法で部分更新することができます。

ページの部分更新はWicketの機能の1つであり,そのために裏側でAjaxを使っている,という意味が伝わるでしょうか。Wicketでは,部分更新したければそのコンポーネントをAjaxRequestTargetに追加するだけでよいのです。あとは,Wicketが裏側で処理をしてくれます。極端に言えば,裏でAjaxが使われていることを知らないとしても,部分更新を行うことができます。

これがWicketの組み込みAjax機能です。

リプライリンクをAjax化する

ページを部分更新する方法が分かりました。早速,TwitterアプリケーションをAjax化してみましょう。まずは,リプライリンクをクリックするとページ全体が再描画されてしまう点を改善しましょう。

サンプルプログラム内にある,jp.gihyo.wicket.page.ajax.AjaxTimelineクラスを見てください。前回作成したPagingTimelineクラスを改良したものです。これから説明するプログラムは,すべてこのクラスに記述されています。

サンプルプログラムでは,replyLinkコンポーネントの次のようにAjaxLinkとして定義し直しました。

リスト3 replyLinkをAjaxLink化した例

item.add(new AjaxLink<Void>("replyLink") {
  @Override
  public void onClick(AjaxRequestTarget target) {
    String targetScreenName = status.getUser().getScreenName();
    form.insertText(target, "@" + targetScreenName + " ");
  }
});

PagingTimelineクラスまでの例では,formのinsertText()メソッドの引数は1つだけでした。今回は引数は2つになり,第1引数としてAjaxRequestTargetを渡しています。実際のフォーム更新処理はinsertText()メソッド内で行われています。

リスト4 入力テキスト欄だけを更新する例

public void insertText(String text) {
  updateText.setModelObject(text);
}

public void insertText(AjaxRequestTarget target, String text) {
  insertText(text);
  target.addComponent(updateText);
  target.focusComponent(updateText);
}

引数が2つの新しいinsertText()メソッドは,まず従来の引数が1つのinsertText()メソッドを呼び出すことで,モデルを更新します。しかし今回は,単にモデルを更新してもページは再描画されません。そこで,テキスト入力欄を表すコンポーネントupdateTextをAjaxRequestTargetに追加することで,入力欄だけを再描画するように指定しました。

さらに,リプライリンクをクリックする場合,ユーザはすぐに入力を行うでしょうから,AjaxRequestTargetクラスのfocusComponent()メソッドを使って,入力フォーカスをupdateTextコンポーネントに移動しています。Wicketではフォーカス制御もこのように簡単に,コンポーネントで指定して行うことができるのです。

リプライリンクをAjax化して入力欄だけを部分更新する手順は,これだけです。Wicketの部分更新機能を使うことで,JavaScriptを意識することなく,ただ「このコンポーネントを再描画してください」と指令することで部分更新が行われるのです。ページの部分更新は,Wicketの標準機能の1つなのです。

著者プロフィール

矢野勉(やのつとむ)

フリーランスのプログラマ。Wicket-ja主催。

ウェブ・アプリケーションの開発を中心にさまざまな案件に関わってきました。現在はWicketによる開発を支援しています。

URLhttp://d.hatena.ne.jp/t_yano/

著書

コメント

コメントの記入