- PR -

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

投稿者投稿内容
Dog
常連さん
会議室デビュー日: 2003/10/16
投稿数: 24
投稿日時: 2006-06-21 13:45
いつもお世話になっております。

JSF(MyFaces1.1.1)を用いた開発を行ってるのですが、
サブウィンドウを開いてFORMを送信する方法について悩んでいます。

[やりたい事]
1.メインウィンドウでh:dataTable等を用いて複数レコード表示。
 ↓
2.各レコードにリンクを設けて、サブウィンドウにFORM情報(選択レコードのID)を送信。
 ↓
3.サブウィンドウでIDをを基に詳細情報取得。

[悩んでいる事]
@h:formをh:dataTable等の繰り返しの中で一意のid属性を与えて使用することは出来ないのでしょうか?(そもそもactionを指定できないのでサブウィンドウ表示の処理には向かないのでしょうか?)
Ah:formを使わずにHTMLのformタグを使用して、サブウィンドウ(の情報取得に使うManagedBean?)にパラメータを引き渡す手法はあるのでしょうか?

@、Aどちらの解決策でも結構ですので、どなたかご存知の方がいらっしゃいましたら、ご教授の程宜しくお願い致します。
でるびすた
常連さん
会議室デビュー日: 2005/06/15
投稿数: 22
投稿日時: 2006-06-22 10:02
@についてはそもそも
h:dataTable 全体を h:form の中に記述する必要があるので
多分できないと思います。

Aについては
<h:dataTable binding="#{someBean}">
のようにコンポーネントバインディングを使って
UIData#getRowData() で選択された行を取得すればできるはずです。

見当違いかもしれませんが参考になれば。
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2006-06-22 11:50
リンクですよね? であれば、h:outputLinkの子要素としてf:paramを指定すれば
渡せるのではないですか? どうしてもPOSTでやらなければいけない理由がありますか?
Dog
常連さん
会議室デビュー日: 2003/10/16
投稿数: 24
投稿日時: 2006-06-22 13:34
ご回答ありがとうございます。

引用:

Aについては
<h:dataTable binding="#{someBean}">
のようにコンポーネントバインディングを使って
UIData#getRowData() で選択された行を取得すればできるはずです。


そうですね、UIData#getRowData()で取得するのが良いようです。
コンポーネントバインディングを使用する方法と併せて、h:dataTableのValueにListではなくDataModelを渡す方法も検討してみたいと思います。
(コンポーネントバインディングはあまり推奨されないという記述を目にした記憶がありまして・・。どうしてなんでしょう、ご存知ですか?)

引用:

リンクですよね? であれば、h:outputLinkの子要素としてf:paramを指定すれば
渡せるのではないですか? どうしてもPOSTでやらなければいけない理由がありますか?


そういえば、h:outputLinkの子要素にf:paramを持つとGETのパラメータになるんでしたね。
特にPOSTでなければということでもないので、この方法も試してみたいと思います。

未記入さん、ukさんありがとうございます。
よしだひろゆき
大ベテラン
会議室デビュー日: 2004/11/22
投稿数: 141
投稿日時: 2006-06-22 20:48
引用:

コンポーネントバインディングを使用する方法と併せて、h:dataTableのValueにListではなくDataModelを渡す方法も検討してみたいと思います。


「よくわかるJavaServer Facesのしくみ」の3.2節に良い例があります。

引用:

(コンポーネントバインディングはあまり推奨されないという記述を目にした記憶がありまして・・。どうしてなんでしょう、ご存知ですか?)


JSFの大きなメリットの一つは、Page Author, Application Developer, Component Writeに必要なスキルセットを分離したことです。
Page Authorは基本的にJSPやHTMLのタグのことだけを知っていればよく、極端な話、Javaのコーディングはできない人でも良い。
Application Developerは逆にJavaによる業務ロジックやDBアクセスのことだけを知っていればよく、JSPやHTMLを知らない人でも良い。JSFのフレームワークのAPIも知らなくてよい。
Component WriterはJSFフレームワークを使って、その両者の間を取り持つ人。

コンポーネントバインディングは、Applicaion DeveloperにコンポーネントAPIを使ったコーディングを強いるので好ましくありません。JSFフレームワークを深く理解している人をたくさん養成しないといけなくなります。
コンポーネントバインディングを使ってできることは、カスタムコーンポーネント化可能なので、一人のComponent Writerががんばって、多数のApplication DeveloperからJSFフレームワークのAPIを隠蔽してあげるのが良いと考えます。

Application Developerが生兵法でコンポーネントAPIに手を出して、「なぜかよく分からないけど、こうやったらできました」というのが一番あぶなっかしいでしょうね。
Dog
常連さん
会議室デビュー日: 2003/10/16
投稿数: 24
投稿日時: 2006-06-23 11:44
よしだひろゆきさん
いつもお世話になっております。

コンポーネントバインディングを使うことで、データではなく制御を受け渡してしまうのでViewとControllerの結合度が上がってしまうのですね。
何もJSFに限ったことじゃなくて、Webアプリ作るなら意識しなきゃいけないことですよね・・。ただ折角JSFを使うのにそのメリットを放棄するようなことは極力しないようにしたいものです。

大変勉強になります。ありがとうございました。

引用:

「よくわかるJavaServer Facesのしくみ」の3.2節に良い例があります。


是非購入して、拝読させていただきたいと思います。

ちなみに本題の件ですがFORMではなく、requestのパラメータ渡しにしました。

[JSP]
<h:outputLink value="SubWindow.jsf" target="SubWindowName">
<h:outputText value="送信"/>
<f:param name="hogeId" value="#{hoge.hogeId}"/>
</h:outputLink>

[faces-config.xml]
<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>hogeId</property-name>
<value>#{param.hogeId}</value>
</managed-property>
</managed-bean>
よしだひろゆき
大ベテラン
会議室デビュー日: 2004/11/22
投稿数: 141
投稿日時: 2006-06-23 13:53
faces-config.xmlの<managed-property>の中でバッキングビーン参照を書くのは
アプリケーションに特性文字列をハードコーディングするのを避けるのに利用できる
良い方法の一つだと思います。

それと、h:datatableで行毎のデータをactionで受け取る簡単な方法として、
actionメソッドをその行データのビーンに置くことがあります。
JSPは以下のようになります。

<h:form>
<h:dataTable var="line" value="#{myBean.lineList}">
<h:column><h:outputText value="#{line.id}"/></h:column>
<h:column><h:outputText value="#{line.data}"/></h:column>
<h:column><h:commandButton value="select" action="#{line.action}"/></h:column>
</h:dataTable>
</h:form>

actionとしてmyBeanのメソッドを指定するのではなくて、lineのメソッドを指定するわけです。
#見当違いな話でしたら御容赦!
Dog
常連さん
会議室デビュー日: 2003/10/16
投稿数: 24
投稿日時: 2006-06-23 18:01
お世話になっております。

引用:

それと、h:datatableで行毎のデータをactionで受け取る簡単な方法として、
actionメソッドをその行データのビーンに置くことがあります。


実は上記方法も検討したのですが、myBean.lineListで保持されるlineがHibernateのhbm2javaで作成したSetter/Getterのみのデータクラスでしたので、actionメソッド的なものを持たせるのは・・と思って断念した訳です。
それでmyBean.lineListをjavax.faces.model.DataModelにして.getRowData()で・・という処理をmyBeanに記述したのですが、「ID渡すだけなのにmyBeanのaction呼ぶ意味ないなぁ」ということでリクエストパラメータで渡すという方法を取った次第です。

JSFを使ったアプリケーションで
@親ウィンドウでレコード選択
A選択レコードの詳細情報を子ウィンドウで表示
の最適な実装方法って他にないものでしょうか?
ちなみにlineのクラスと子ウィンドウのバッキングビーンクラスは別クラスです(当り前ですか?)。
紹介されているWebページや書籍の情報でも構いませんので、ご存知でしたらご教授下さい。
(よしだひろゆきさん著の書籍は未だ拝読しておりません。今週末にでも。)

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