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レンダリングの概念図である。
先述した通り、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('');
setFocus('');
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の機能を実現している。