- PR -

JSFでサブウィンドウにFORM送信

投稿者投稿内容
よしだひろゆき
大ベテラン
会議室デビュー日: 2004/11/22
投稿数: 141
投稿日時: 2006-06-26 09:51
引用:

myBean.lineListで保持されるlineがHibernateのhbm2javaで作成したSetter/Getterのみのデータクラスでしたので、actionメソッド的なものを持たせるのは・・と思って断念した訳です。


あくまでも一般論ですが、ビジネスロジック側が提供するデータがJSFの想定と合わない場合には、JSF側の機能を駆使していじくるよりは、ラッパークラスを作成するのが良いと思います。ビジネスロジックの担当者にはできるだけJSFの色々なことを理解しないでも仕事ができるようにしたいからです。
引用:

それでmyBean.lineListをjavax.faces.model.DataModelにして.getRowData()で・・という処理をmyBeanに記述したのですが、「ID渡すだけなのにmyBeanのaction呼ぶ意味ないなぁ」


「よくわかる…」で解説しているのはまさにその方法です
JSFはactionを呼んで、その結果(outcome)を使ってNavigation Handlerがfaces-config.xmlの指定に従って次の処理を決める、というのが基本ですから、私は「呼ぶ意味ない」とはあまり思いませんね。
t_yamo
常連さん
会議室デビュー日: 2006/02/16
投稿数: 21
投稿日時: 2006-06-26 12:33
既によしださんが考え方について記されているので、蛇足になりますが、具体的な実装例をば。

引用:
JSFを使ったアプリケーションで
@親ウィンドウでレコード選択
A選択レコードの詳細情報を子ウィンドウで表示
の最適な実装方法って他にないものでしょうか?



最適な実装方法はわかりませんが、自分の場合はDataModelを使います。

データ量にもよりますが、例えば「一覧で選択したユーザの詳細情報を表示」という機能であれば、DataModelの中にユーザのリストをそのまま投入して一覧表示(記述例:<dataList value="context.getDataModel()">)します。
で、選択されたデータはgetRowData()で取得してそれをもとに詳細情報を表示します。

この方法だと、プレゼンテーションをいじる人が「この情報のキーはユーザIDだな」なんていうことすら意識しないで済み、一覧画面にせよ詳細画面せよ、ユーザクラスが持つフィールドを【プレゼンテーション開発者が】好きに画面に配置することができます。
また、任意の項目をoutputTextではなくinputTextにすれば、一覧画面/詳細画面を問わず変更可能項目にできます。

なお、ここでcontextを「リクエストスコープ」よりも大きいスコープに定義しておき、
 getDetail() { return (User) getDataModel().getRowData(); }
といったメソッドをcontextのクラスに追加してあげると、詳細画面では
 #{context.detail.userName}
と書くことができるため、処理の分岐をしないのであればaction関係のメソッド定義も省略できます。

#詳細情報の表示機能だけであれば、それが「画面遷移で表示する」のか
#あるいは「サブウィンドウで表示する」のかというのはロジック側では
#一切気にしないでいいはずです。


【追記】
この方法であれば、「myBean.lineListで保持されるlineがHibernateのhbm2javaで作成したSetter/Getterのみのデータクラス」でOKであり、actionをlineに入れる必要はありません。
また「ID渡すだけなのにmyBeanのaction呼ぶ」ということもありません。
そもそも「IDを渡す」という動きをしませんね。


[ メッセージ編集済み 編集者: t_yamo 編集日時 2006-06-26 12:44 ]

[ メッセージ編集済み 編集者: t_yamo 編集日時 2006-06-26 12:46 ]
Dog
常連さん
会議室デビュー日: 2003/10/16
投稿数: 24
投稿日時: 2006-06-27 16:25
よしだひろゆきさん、t_yamoさんご回答ありがとうございます。

引用:

JSFはactionを呼んで、その結果(outcome)を使ってNavigation Handlerがfaces-config.xmlの指定に従って次の処理を決める、というのが基本ですから、私は「呼ぶ意味ない」とはあまり思いませんね。


確かにそうですね・・。メイン画面の遷移はアクションを呼び出して、navigation-ruleで遷移を定義しているのに、サブウィンドウだけリンクで呼び出してリクエストパラメータを渡すのはちょっと違和感がありますし。

最終的に実装した手法を記述させていただきます。(navigation-case等多少割愛した部分があります)
[一覧JSP]
<h:commandLink action="#{listController.select}" target="SubWindowName">
<h:outputText value="参加"/>
</h:commandLink>

[faces-config.xml]
<managed-bean>
<managed-bean-name>listController</managed-bean-name>
<managed-bean-class>hoge.ListController</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>

<managed-bean>
<managed-bean-name>subWindowController</managed-bean-name>
<managed-bean-class>hoge.SubWindowController</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>hoge</property-name>
<value>#{listController.selected}</value>
</managed-bean>

<navigation-rule>
<from-view-id>/MainWindow.jsp</from-view-id>
<navigation-case>
<from-outcome>sub</from-outcome>
<to-view-id>/SubWindow.jsf</to-view-id>
</navigation-case>
</navigation-rule>

[ListController.java]
private DataModel hogeList;
private Hoge selectedHoge;
public String select(){
if (hogeList != null) {
selectedHoge = (Hoge) hogeList.getRowData();
}
return "sub";
}
public Hoge getSelected() {
return selectedHoge;
}
・・・

[SubWindowController.java]
private Hoge hoge;
public void setHoge(Hoge hoge) {
this.hoge = hoge;
}
・・・

t_yamoさんにご教授頂いた方法で実装しようとしたのですが、サブウィンドウ側でも付随情報の取得等独自の処理があり、リスト側で持つオブジェクトを参照するのではなく、faces-config.xmlの中でオブジェクト渡しを定義することにしました。
([蛇足]h:commandLinkって解釈時にonclickが入るのでonclickの指定が出来ないんですね。window.open()したかったのに・・。)

ご教授頂きありがとうございました。
また質問させて頂くことがあると思いますが、どうぞ宜しくお願い致します。
t_yamo
常連さん
会議室デビュー日: 2006/02/16
投稿数: 21
投稿日時: 2006-06-28 12:40
実装方法は既に決定されたとのことですので参考情報として記します。

「リスト側で持つオブジェクトを参照するのではなく」とありますが、提示して頂いたコードではhogeIdなどのキー項目ではなくオブジェクト自体を渡していますので、リスト側で持つオブジェクトを参照していることになります。
(提示して頂いたコードと私の書き込みの違いは、サブウィンドウ用コントローラに遷移後のデータを格納するか否かの部分だと思います。私の書き込みではsessionスコープのDTOにデータを格納しています)

また、以下のようにするとactionメソッドなしで記述できます。

[一覧JSP]
<h:commandLink action="sub" target="SubWindowName">
<h:outputText value="参加"/>
</h:commandLink>

[ListController.java]
private DataModel hogeList;
public Hoge getSelected() {
if (hogeList != null) {
return (Hoge) hogeList.getRowData();
}
return null;
}
・・・

スキルアップ/キャリアアップ(JOB@IT)