- - PR -
MyFaces x:treeのイベントリスナに関して
1
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2006-05-25 15:39
お世話になっております。
ただいまJSF(MyFaces)を用いた開発を行っております。 JSPの中でMyFacesの拡張タグである<x:tree>を用いたビューの作成をしているのですが、<x:treeSelectionListner>の挙動がビューに反映されず困っています。 ■目的 Tree.jspのツリーをクリックしたイベントで<h:inputText id="focus"/>の値を変化させたい。 ***Tree.jsp*** <f:view> <h:form id="test"> <h:inputText id="focus" value="#{treeBean.focus}" /> <x:tree id="tree" value="#{treeBean.tree}" nodeClass="treenode" selectedNodeClass="treenodeSelected" expandRoot="true"> <x:treeSelectionListener type="controller.TreeAction" /> </x:tree> </h:form> </f:view> ***faces-config.xml*** (略) <managed-bean> <managed-bean-name>treeBean</managed-bean-name> <managed-bean-class>controller.TreeBean</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> ***TreeBean.java*** public class TreeBean implements Serializable { private TreeModel tree; private MutableTreeNode root; private String focus; public TreeBean(){ root = new MutableTreeNode("ROOT"); (略) tree = new DefaultTreeModel(root); //@focusに初期値をセット focus = "default"; } public TreeModel getTree() { return tree; } public void setTree(TreeModel tree) { this.tree = tree; } public String getFocus() { return focus; } public void setFocus(String focus) { this.focus = focus; } } ***TreeAction.java*** public class TreeAction implements TreeSelectionListener{ public TreeAction(){ super(); } public void valueChanged(TreeSelectionEvent event) { FacesContext context = FacesContext.getCurrentInstance(); TreeBean tree = (TreeBean)context.getApplication().getVariableResolver().resolveVariable(context,"treeBean"); //Afocusの値を変更 tree.setFocus("update"); } } @で初期化したfocusプロパティに対し、ツリークリック時のイベントTreeAction(リスナクラス)の中でAのようにsetメソッドで値をセットしています。 一旦は値がセットされているようなのですが、TreeAction→JSPの表示の間にでもう一度TreeBean.setFocus()が呼ばれ、以前(前画面)のfocusプロパティがセットし直されているようです。 ※TreeBean.setFocusを空のダミーメソッドとして、Aで別のsetter(例TreeBean.setFocus2())からセットするという解決方法もありますがスッキリしません・・。 初歩的なJSFのライフサイクルの問題なのかもしれませんが、解決できず困っています。 どなたかご存知の方がいらっしゃいましたら、ご教授いただけませんでしょうか? 宜しくお願い致します。 | ||||||||
|
投稿日時: 2006-05-26 13:52
MyFace(Tomahawk)の使用経験が無くて恐縮ですが...
一般的にValueChangeEventはProcess Validationsフェースで処理されます MyFacesのTreeSelectionEventもおそらくそうなのではないでしょうか. その後のModel Values Updateフェーズで入力値をバッキングビーンに設定します. ですから現象のようなことが起きているのだと思います. PhaseListenerを設定してフェーズ名をロギングしてみると,上記が確認できると思います. 回避方法は二つ (1)Model Values UpdateとInvoke Applicationフェーズを完全にスキップしてかまわないのであれば, リスナーの中でfacesContext.renderResponse()を呼びます. (2)Model Values UpdateとInvoke Applicationフェーズをスキップして困る場合は, Eventの処理をModel Values Updateフェーズの後で実行するようにします. こんな感じでできるのではないでしょうか? if (!event.getPhaseId().equals(PhaseId.UPDATE_MODEL_VALUES)){ UIComponent comp = event.getComponent(); event.setPhaseId(PhaseId.UPDATE_MODEL_VALUES); comp.queueEvent(event); } else { // 通常の処理 } | ||||||||
|
投稿日時: 2006-05-26 17:48
よしだひろゆき様 ご回答ありがとうございます。
その通りだったようです。 ご教授いただいた回避方法を試してみました。
問題解決と同時に非常に勉強になりました。ありがとうございました。 | ||||||||
|
投稿日時: 2006-05-29 14:17
そうです.renderResponseフラグが立っていると,次はRender Responseフェーズになります. ちなみにresponseCompleteというフラグもあって,これが立つとライフサイクルを終了します
そうです.一度Process Validationsフェーズで実行されて,その時にif-then部分を 実行してキューイングし直します.Model Values Updateフェーズでは再びブロード キャストされてelse部分を実行します. | ||||||||
|
投稿日時: 2006-05-30 18:12
返信が遅くなってしまいました・・。
よしだひろゆき様 丁寧なご回答ありがとうございました。 やはりイベントリスナのような局所的なところだけでなく、リクエストがどのようなフェーズで処理されるかという全体的な理解が必要なのですね。 |
1