3.JSFのライフサイクル(アプリケーションの起動フェーズまで)

Ajaxブリッジから送信された部分的なリクエストに対応するため、該当するJSFコンポーネントにフラグを立て、コンポーネントツリーの一部のみをJSFライフサイクルの処理対象としている。ICEfacesでは、このようなXHRによる部分的なサブミットを、パーシャルサブミット(Partial Submit)と呼んでいる。

ここで実行されるのは、JSFのライフサイクルそのもの(Lifecycle#execute()メソッド、およびLifecycle#render()メソッド)である。つまり、JSFで用意されている仕組み(バリデータ、コンバータ、イベント、リスナなど)をそのまま利用することが可能である。

先に紹介したアドレスフォームの2つの動作例(Ajaxアプリケーションの典型的機能)は、いずれもJSFの機能を活用することで実現している。

(A) JSFのカスタムコンバータを用い、文字列の変換を実施している

(B) JSFのバリューチェンジリスナを用い、Cityの値が変更されると、対応するStateおよびZipの値を取得する。また、JSFのフェーズリスナを定義し、アプリケーション起動フェーズの後に、City、State、Zipの値を、マネージドビーンに反映する

4.JSFのライフサイクル(レンダリングフェーズ)

アプリケーションを起動し、ビジネスロジックを終了したら、レスポンスのレンダリング(Render Response)フェーズとなる。ICEfacesのレンダリングは、D2D(Direct-to-DOM)レンダリングと呼ばれている。図2は、D2Dレンダリングの概念図である。

図2: D2Dレンダリング

先述した通り、ICEfacesでは、サーバサイドにもDOMツリーを保持している。変更のあったJSFのUIコンポーネントは、D2Dレンダラキット(JSFのレンダラの拡張)を介して、サーバサイドでキャッシュしているDOMツリーの内容を更新する。

5.レスポンスの送信

変更されたDOMの内容は、レスポンスデータへとシリアライズされ、クライアントに渡される。具体的には、リスト2のようなXML形式のデータが、レスポンスとして返される。

リスト2: Ajaxブリッジから返されるレスポンス

<updates>
    <update address="_id17:lastName">
        <![CDATA[
        <input
            accesskey="L"
            class="iceInpTxt textField"
            id="_id17:lastName"
            name="_id17:lastName"
            onblur="setFocus(&#39;&#39;);
                    setFocus(&#39;&#39;);
                    iceSubmitPartial(form,this,event);
                    return false;"
            onfocus="setFocus(this.id);"
            onkeypress="iceSubmit(form,this,event);"
            style="width:120px;"
            tabindex="30"
            type="text"
            value="Ashiwa">
        </input>
        ]]>
    </update>
</updates>

シリアライズする際には、更新されるHTMLの要素ごとにupdateタグが書き出される。クライアント側のAjaxブリッジでは、address属性で指定されたID(ここでは、_id17:lastName)を持つ要素を、update要素のデータ内容で更新する。

このような、部分的な変更の反映を、ICEfacesでは、インクリメンタルDOMアップデート(Incremental DOM Updates)と呼んでいる。

なお、リスト2のデータ(inputタグ)にはイベント属性(onblur、onfocus、onkeypress)があり、JavaScriptが記述されている。説明が前後してしまったが、ICEfacesのカスタムコンポーネント(カスタムレンダラ)では、このようなイベント属性を付加し、Ajaxブリッジにて用意されている関数を呼んでいる。JavaScriptは、カスタムコンポーネント内とAjaxブリッジ内に隠蔽されているため、開発者は、カスタムタグを記述するだけでAjaxの機能を実現することができる。

ICEfacesではこのようにして、JSFにてAjaxの機能を実現している。