実際の値は正しく処理されますが、ビューが即時アクションから戻るたびに、一連のラジオ ボタンが選択されていない状態にリセットされるというシナリオに遭遇しました。ビューを更新しても、正しい値が表示されます。奇妙なことに、この動作は、コンポーネントがコンバーターを使用し、コンポーネント内にない場合にのみ発生ui:repeat
します。次の例に絞り込みました。
JSFページ
<ui:repeat value="#{bean.stringList}" var="item" varStatus="iteration">
#{item}
<h:selectOneRadio value="#{bean.boolValue}" rendered="#{iteration.last}">
<f:selectItems value="#{bean.boolItemList}" />
<f:converter converterId="testConverter" />
</h:selectOneRadio><br /><br />
</ui:repeat>
<hr />
<h:selectOneRadio value="#{bean.stringValue}">
<f:selectItems value="#{bean.stringItemList}" />
</h:selectOneRadio>
<h:selectOneRadio value="#{bean.boolValue}">
<f:selectItems value="#{bean.boolItemList}" />
<f:converter converterId="testConverter" />
</h:selectOneRadio>
<p>
<h:commandButton value="Submit" type="submit" />
<h:commandButton value="Do nothing, but immediate!" immediate="true" action="#{bean.doNothing}" />
</p>
<p>boolValue is: #{bean.boolValue}</p>
バッキングビーン
@ManagedBean(name = "bean")
@SessionScoped
public class Bean {
private List<String> stringList;
private List<SelectItem> stringItemList;
private List<SelectItem> boolItemList;
private boolean boolValue;
private String stringValue;
private int removeParam;
public Bean() {
stringList = new ArrayList<String>();
stringList.add("Test Item One");
stringList.add("Test Item Two");
stringItemList = new ArrayList<SelectItem>();
stringItemList.add(new SelectItem("1", "Option One"));
stringItemList.add(new SelectItem("2", "Option Two"));
boolItemList = new ArrayList<SelectItem>();
boolItemList.add(new SelectItem(Boolean.TRUE, "This is real"));
boolItemList.add(new SelectItem(Boolean.FALSE, "This is not real"));
}
// + getters and setters
public void doNothing(){
}
}
コンバータ
@FacesConverter("testConverter")
public class TestConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value)
{
if (value!= null) {
if (value.equals("real"))
{
return Boolean.TRUE;
}
}
return Boolean.FALSE;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
boolean check = (Boolean) value;
if (check) return "real";
else return "unreal";
}
}
したがって、次のようになります。
- のバッキング Bean リストから作成さ
SelectItem(String, String)
れ、String に保存されたラジオ ボタンのグループ。コンバーターは必要ありません。 - のバッキング Bean リストから構築され
SelectItem(boolean, String)
、ブール値に保存されたラジオ ボタンのグループ。ブール値をいくつかの単語 ("real"/"unreal") にマップするためのコンバーターが提供されています - 標準のコンバーター ("true"/"false") を置き換えるだけです。 - 送信ボタン + 値が正しく設定されているかどうかをテストするための出力。
- JSF ライフサイクルを変更する以外に何もしない、いくつかの即時アクションを持つボタン。
これにより、遊んで次のことを観察できます。
- ページが即時アクションから戻るたびに、コンバータが外部
ui:repeat
にある無線には値が表示されません。つまり、無線が選択されていません。 - ただし、値は実際には送信時に正しく設定されます。ページを更新すると、ラジオが正しく設定されます。
- 内部の同じ無線グループは問題なく動作し、コンバーターのないものも同様です
ui:repeat
より良い知識に照らしてテストしたところ、コンバータラジオが同じエラー<c:foreach>
を表示するのではなく、内部に配置されていることを確認しましたui:repeat
(これは、ツリーを構築してから消えるだけなので、予想どおりです)。ラジオはそれらを壊しません。BalusC のコメントに関しては、Bean を ViewScoped に変更しても問題には影響しません。その場合のみ、リフレッシュするとデフォルトで初期化された空白のページが表示されます。
ここで私は私の知識の終わりにいます。これをさらに減らす方法や、なぜこのように動作するのか、私にはよくわかりません。それで...ええと...誰かアイデアはありますか?
サーバー担当者から入手した仕様: Mojarra JSF API 実装 2.0.5-FCS、JSF 2.0、および Facelets、サーバーは Weblogic 11g 10.3