[英]Radio button is reset after immediate action (converter and ui:repeat mysteriously involved)
I came across a scenario were a set of radio buttons gets reset to a none-selected state whenever the view returns from an immediate action, although the actual value is processed correctly. 我遇到了一个场景,尽管视图的正确值得到了正确处理,但只要视图从即时操作返回,就会将一组单选按钮重置为未选择状态。 Refreshing the view also displays the correct value. 刷新视图也会显示正确的值。 Weirdly enough, the behavior does only occur when the component uses an converter and is not inside a ui:repeat
I narrowed it down to the following example: 古怪的是,当组件使用的转换器,是不是里面也只发生行为ui:repeat
我把范围缩小到了下面的例子:
<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";
}
}
So we have: 因此,我们有:
SelectItem(String, String)
, saved to a String. 从SelectItem(String, String)
的后备bean列表构建的一组单选按钮,保存到String。 No converter needed. 无需转换器。 SelectItem(boolean, String)
, saved to a boolean. 从SelectItem(boolean, String)
的后备bean列表构建的一组单选按钮,保存到布尔值。 A converter is provided to map the boolean to some words ("real"/"unreal") - just to replace the standard converter ("true"/"false") 提供了一个转换器来将布尔值映射到某些单词(“真实” /“虚幻”)-只是替换标准转换器(“ true” /“ false”) With this, one can play around and observe the following: 有了它,人们可以玩转并观察以下内容:
ui:repeat
display no value, meaning: no radio is selected 每当页面从立即操作返回时,带有ui:repeat
之外的转换器的无线电都不会显示任何值,这意味着:未选择任何无线电 ui:repeat
works just fine, as does the one without the converter 内 相同的无线电组ui:repeat
工作得很好,一样没有变流器的一个 Testing around against better knowledge I checked that the converter-radios put inside a <c:foreach>
instead of ui:repeat
show the same error (which is as I would have expected, as it merely builds the tree and then vanishes) and that attaching some standard converter to the string-radios does not make them break. 围绕更好的知识进行测试,我检查了放置在<c:foreach>
而不是ui:repeat
内的转换器无线电是否显示相同的错误(这是我所期望的,因为它只是构建树然后消失了),并且将一些标准转换器连接到字符串收音机不会使它们折断。 Regarding BalusC's comment, changing the bean to ViewScoped does not affect the problem - only then, refresh gives you a blank default-initialized page. 关于BalusC的注释,将Bean更改为ViewScoped不会影响该问题-只有这样,刷新才会为您提供空白的默认初始化页面。
Here I am at the end of my knowledge. 我的知识到此为止。 I don't really see how to reduce this any further or why it behaves like this. 我真的没有看到如何进一步减少它,或者为什么它表现得如此。 So... well... ideas anybody? 所以...好吧...有人有想法吗?
Specs I got from the server guy: Mojarra JSF API Implementation 2.0.5-FCS, JSF 2.0 and Facelets, Server is a Weblogic 11g 10.3 我从服务器人员那里得到的规格:Mojarra JSF API实施2.0.5-FCS,JSF 2.0和Facelets,服务器是Weblogic 11g 10.3
I still have no real understanding of why it behaves this way, but I found two solutions. 我对它为什么会这样仍然没有真正的了解,但是我找到了两种解决方案。
1) The doNothing()
method does not comply with the spec , which demands that the signature must match java.lang.Object action()
1) doNothing()
方法不符合spec ,它要求签名必须与java.lang.Object action()
相匹配
If I correctly add a return value to go back to the same page (either through the file name "test.xhtml" or through outcome
and navigation-rule
in the faces-config), everything works fine. 如果我正确添加了返回值以返回同一页(通过文件名“ test.xhtml”或通过faces-config中的outcome
和navigation-rule
),则一切正常。
2) If I add f:ajax
to the button to execute and re-render part of the page everything is well. 2)如果我在按钮上添加f:ajax
以执行并重新渲染页面的一部分,则一切正常。 I played around a bit and it does not seem to matter what part of the page is executed/re-rendered (other than the normal effects in applying values and such). 我玩了一会儿,似乎页面的哪一部分执行/重新渲染并不重要(除了应用值等的正常效果外)。
I am still a bit confused by the initially rather random behavior (and how ui:repeat and converters influence it). 我仍然对最初的随机行为(以及ui:repeat和转换器如何影响它)感到困惑。 It seems that my understanding of how JSF returns to a page without explicit navigation is incomplete. 似乎我对JSF如何在没有显式导航的情况下返回页面的理解是不完整的。 This also applies to getting back after failed validation via FacesContext#renderResponse
. 这也适用于通过FacesContext#renderResponse
验证失败后返回。 Any help appreciated (I could also open a new question if appropriate and then edit this answer) 任何帮助表示赞赏(如果合适,我也可以打开一个新问题,然后编辑此答案)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.