Click勉強記 その3 〜ActionLinkのコールバック

前回までで表示をやりました。ですが

$editLink  → <a href="...">編集</a>

という変換になっているだけです。ActionLinkは基本的にクリックされたときにPageインスタンスのメソッドがコールされることを想定して作られているので実際にこのコールバックを受けてみましょう。

まず、addControl前に

        editLink.setListener(this, "onEditLink");
        addControl(editLink);

こんなことになっていました。このthisはaddControlを記述したPageクラスのインスタンスで、onEditLinkメソッドはこのクラスに記述しなくてはなりません。

ということは、このeditLinkというActionLinkが生成するアンカーのリンク先は同じページ(同じPageクラスへのマッピング)ということになります。これに加えてどのActionLinkがクリックされたか、という情報を持っています(複数のActionLinkがページ上に登場したときに特別するためです)。

実際にonEditLinkメソッドを定義して確認してみると

    public boolean onEditLink() {
        System.err.println("onEditLink --");
        return true;
    }

クリックするとたしかにこのメソッドが走っていることがわかります。戻り値は後続処理を行なうかどうかをClickに指示するためのものです。trueなら続行しますし、falseなら打ち切りです。使いどころはありますが、最初は特に意識しなくてもいいでしょう。



ところで、ActionLinkはコールバック関数に対して(厳密には自身のActionLinkインスタンスに対して)一つだけパラメータを受け渡す機能があります。この場合、HTMLビュー側で以下のように書きます。

<a href="$editLink.getHref(100)">ほげ</a>

ActionLinkは getHrefメソッドで href部分だけ取り出すことが出来ますので、このような使い方をすることができます。この使い方ですとややデザイナー/HTMLエディタフレンドリーになりますね。

任意の型の引数を付けることが出来ますが、toString()した値が使われることになります。パラメータは value=hogehoge というような付き方がします。

この値はActionLinkのインスタンスvalueプロパティにセットされています*1

ですので、これを参照するならば

    public boolean onEditLink() {
        String id = _editLink.getValue();
    .
    .

というようなコードになります。このgetValue()はユーティリティメソッドとして

  • Doubleを返す getValueDouble()
  • Integerを返す getValueInteger()
  • Longを返す getValueLong()

なんかも用意されています。プリミティブ型ではないです。nullハンドリングのためですね。

と、ここまでの内容でテーブル形式のものにActionLinkで作られるリンクを貼り付けて単一のコールバックメソッドで処理することが可能になったわけです。これでイベントドリブン的にプログラミングできますね*2



と、ちょっと内容は薄いのですがひとまずここまでメモってみました。

以下、ちょっと蛇足です。

リスナーのディスパッチ先もPageのコンストラクタもしくはonInit()で実施されていることから、ちょっと変わった挙動を示している気もします。たとえばディスパッチ先のインスタンスにthis以外を指定することもできますが、このイベントをハンドルできるPageクラスは「同様の条件でaddControl()が走るもの」に限定されます。これは、PageもControlもライフサイクルがリクエストスコープだからです。コールバックについての情報を持ってHTTPリクエストが飛んでくるわけではなくて、コールバック先の情報ですらリンククリック先のPageクラスの初期化処理で再度実施されているわけです。
とはいえ、ActionLinkの飛び先(href)は、表示しているページと同一のURIに飛ばされますから、こんなことを意識する必要はあまりないでしょう。ActionLinkはアンカーを生成するためのコントロールではなくて、コールバックなアンカーを仕掛けるためのものと限定していいわけです。ただし、ActionLinkを設置するPageクラスが、初期化フェーズでDaoやServiceへの問い合わせ処理が毎回走行するようなケースではパフォーマンスにもある程度ケアが必要かもしれません。

*1:Clickのフレームワークとしてのシーケンス(アクティビティ)で、コントロールに対してリクエストを通知する個所があり、ここでActionLinkは自分がクリックされたかどうかを識別して自身のプロパティをセットしています

*2:蛇足ではありますが、これはContinuationsなどとは似て非なるインタラクションです。将来Clickにもcontinuationsサポートが付く可能性はあるんじゃないかなーと思ってますが