我遇到了一个场景,即当视图从立即操作返回时,一组单选按钮被重置为未选择状态,尽管实际值被正确处理。刷新视图也会显示正确的值。奇怪的是,该行为仅在组件使用转换器且不在内部时才会发生,我将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)
,保存到字符串。无需转换器。 - 一组单选按钮,由 的支持 bean 列表构建
SelectItem(boolean, String)
,保存为布尔值。提供了一个转换器来将布尔值映射到一些单词(“real”/“unreal”) - 只是为了替换标准转换器(“true”/“false”) - 提交按钮 + 输出以测试值是否设置正确。
- 一个带有一些即时操作的按钮,除了改变 JSF 生命周期之外什么都不做。
有了这个,人们可以玩耍并观察以下内容:
- 每当页面从即时操作返回时,带有转换器的收音机不
ui:repeat
显示任何值,这意味着:没有选择收音机 - 但是,该值实际上在提交期间设置正确。刷新页面将导致正确设置收音机。
- 内部相同的无线电组工作正常,没有转换器的无线电组也可以
ui:repeat
根据更好的知识进行测试,我检查了转换器无线电放在 a<c:foreach>
中而不是ui:repeat
显示相同的错误(正如我所预料的那样,因为它只是构建树然后消失),并且将一些标准转换器附加到字符串 -收音机不会让它们坏掉。关于 BalusC 的评论,将 bean 更改为 ViewScoped 不会影响问题 - 只有这样,刷新才会为您提供一个空白的默认初始化页面。
在这里,我的知识已经走到了尽头。我真的不知道如何进一步减少这种情况或为什么它会这样。所以...嗯...想法有人吗?
我从服务器人那里得到的规范:Mojarra JSF API Implementation 2.0.5-FCS、JSF 2.0 和 Facelets,服务器是 Weblogic 11g 10.3