明確に描いている記事を見かけなかったので…
テーブル等でデータをループして描画する際、CSSデザインの適用などの問題を考えて
data tableは使わずにすべて
その中で気がついたことなどメモ
if文を使いたくて、を使ってみたんですが訳の分からないことになった…
どうやら解析のタイミングに違いがあるようで、JSF→JSTの順だったかな?
になるため、repeatしてからif文の解釈されるので、全行に最終行の結果が反映される事態に。
素直に
ViewScope以上なら気にすることはありません。
Springとの連携をしている影響で、ViewScopeが使えないため起こった事態。
なんやかんやして同じ画面に戻ってくる、という処理をしたかったわけですが。
ループ内にhidden項目を突っ込むだけでは、Bean内のListを再構築してくれませんでした…
どうも、突っ込むための枠は作ってくれないご様子。
枠があれば突っ込まれてくれる。
(Beanのコンストラクタ内で固定で3つインスタンスをaddしたら受け取ってくれた)
しかし、動的に行数が変わるし、コンストラクタも
Beanへのパラメータセット前に動かされるから、パラメータで行数を渡すこともできない
ええいこうなったらSessionScopeだ…の前に、
※今回はどのボタンからも渡したかったので、普通に
こういった形で私たパラメータは、
こんなかんじ
これなら
画面側で行数を適当なinput hiddenに放り込んで、上記の方法で取得して、
取得した件数分ループさせてListにインスタンスをぶっこむ、という方法を取りました。
この辺もうちょっと、もうちょっと何とかしてくれないかなあ
ちなみに、このあたりはコンボボックスも同じような感じ。
めんどくせえ…
コンボボックスの選択肢生成に
そんな値存在しません!みたいなエラーで怒られる
単純な名称のリストとかなら
必要なパラメータだけsessionに突っ込んでおくか、上記の
ある意味厳密にチェックしてくれるから便利な側面もあるんだろうけど、個人的にはめんどい。
■
のようにすると、dataを使ってパラメータにアクセスできるようになるけど、
描画やActionへのパラメータ渡しならともかく、
■
描画側にしか使わないから!と、Bean側のListの初期化を怠っていると
アクションパラメータにセットした値が渡されないのである。
いやこれは本当わからなかった。
たとえば、
としてあって、
みたいなことがしたかった場合、このdataListのvalueが、
展開後のソース見てもいまいちピンとこなかったけど、どうやらaction内に定義した内容って、画面側で展開してどうにかしているわけじゃなくて、一回サーバーに返してサーバー上でデータとって来たりなんなりして、再解析?して動かしてるっぽい。
そのため、引数として渡すパラメータもちゃんとBeanに再構築されていないとnullが渡ってしまうという。
もっかい言うけどめんどくせえ
テーブル等でデータをループして描画する際、CSSデザインの適用などの問題を考えて
data tableは使わずにすべて
ui:repeat
で描画しているのですが、その中で気がついたことなどメモ
■JSTLのタグと混ぜて使わない
if文を使いたくて、
ui:repeat
内でどうやら解析のタイミングに違いがあるようで、JSF→JSTの順だったかな?
になるため、repeatしてからif文の解釈されるので、全行に最終行の結果が反映される事態に。
素直に
ui:fragment
を使いましょう。チャンポンダメ・ゼッタイ■RequestScopeの場合は、毎回初期化&必要件数のインスタンス化が必要
ViewScope以上なら気にすることはありません。
Springとの連携をしている影響で、ViewScopeが使えないため起こった事態。
ui:repeat
で画面に描画した後になにかしらボタンを押してrequestを投げ、なんやかんやして同じ画面に戻ってくる、という処理をしたかったわけですが。
ループ内にhidden項目を突っ込むだけでは、Bean内のListを再構築してくれませんでした…
どうも、突っ込むための枠は作ってくれないご様子。
枠があれば突っ込まれてくれる。
(Beanのコンストラクタ内で固定で3つインスタンスをaddしたら受け取ってくれた)
しかし、動的に行数が変わるし、コンストラクタも
@PostConstract
もBeanへのパラメータセット前に動かされるから、パラメータで行数を渡すこともできない
ええいこうなったらSessionScopeだ…の前に、
ExternalContext
を試すことに。commandButton
内でf:param
を使うと、特定のボタンを押したときだけhiddenでパラメータを渡すことができます。※今回はどのボタンからも渡したかったので、普通に
input type="hidden"
を使いましたが。こういった形で私たパラメータは、
ExternalContext
を介してGet出来ますこんなかんじ
FacesContext context = FacesContext.getCurrentInstance();
String value = context.getExternalContext().getRequestParameterMap().get("value");
これなら
@PostConstruct
内で、画面に表示した行数がわかる!ということで、画面側で行数を適当なinput hiddenに放り込んで、上記の方法で取得して、
取得した件数分ループさせてListにインスタンスをぶっこむ、という方法を取りました。
この辺もうちょっと、もうちょっと何とかしてくれないかなあ
ちなみに、このあたりはコンボボックスも同じような感じ。
めんどくせえ…
コンボボックスの選択肢生成に
f:selectItems
等を利用する場合、@PostConstruct
で該当のリストを生成していないとバリデーション?エラーになるというお話。そんな値存在しません!みたいなエラーで怒られる
単純な名称のリストとかなら
@PostConstruct
内でDB見に行くなりすればいいんだけど、その時画面に表示している値によってコンボの内容を切り替えなきゃいけないような場合、どーすんの?と思った。必要なパラメータだけsessionに突っ込んでおくか、上記の
ExternalContext
を利用するしかなさげ。ある意味厳密にチェックしてくれるから便利な側面もあるんだろうけど、個人的にはめんどい。
■ui:repeat
内のパラメータの渡し方
ui:repeat value="#{hogehoge.dataList}" var="data" varStatus="stat"
のようにすると、dataを使ってパラメータにアクセスできるようになるけど、
描画やActionへのパラメータ渡しならともかく、
h:inputHidden
では使えない。#{hogehoge.dataList[stat.index].value}
のように、indexを使ってセットする必要があり。■ui:repeat
内のパラメータをアクションの引数に渡すこと
描画側にしか使わないから!と、Bean側のListの初期化を怠っていると
アクションパラメータにセットした値が渡されないのである。
いやこれは本当わからなかった。
たとえば、
ui:repeat value="#{hogehoge.dataList}" var="data" varStatus="stat"
としてあって、
h:commandLink action="#{hogehoge.register(data.value)}"
みたいなことがしたかった場合、このdataListのvalueが、
h:inputHidden
を使ってちゃんとBeanに再構成されるようになっていないと動作しない。展開後のソース見てもいまいちピンとこなかったけど、どうやらaction内に定義した内容って、画面側で展開してどうにかしているわけじゃなくて、一回サーバーに返してサーバー上でデータとって来たりなんなりして、再解析?して動かしてるっぽい。
そのため、引数として渡すパラメータもちゃんとBeanに再構築されていないとnullが渡ってしまうという。
もっかい言うけどめんどくせえ