我想处理这个表单(valueChangueListener在实际情况下无效)。
这是后豆:
public class TestBean extends PrivateBaseBean implements Serializable {
private List<String> strings;
@PostConstruct
public void init() {
strings = new ArrayList<String>();
strings.add("");
strings.add("");
strings.add("");
}
public void saveAction(ActionEvent event) {
StringBuilder textToShowInMessage = new StringBuilder();
for (String string : strings) {
textToShowInMessage.append(string);
textToShowInMessage.append("; ");
}
FacesMessage msg = new FacesMessage(super.getBundle().getString(
textToShowInMessage.toString()), "");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
getters... setters...
观点:
....
<h:form>
<ui:repeat var="string" value="#{testBean.strings}">
<h:inputText value="#{string}" />
<br />
</ui:repeat>
<p:commandButton value="#{msg.save}"
actionListener="#{testBean.saveAction}" icon="ui-icon-disk"
update="@form" />
</h:form>
...
在后面的bean字符串列表中处理表单时,总是空白。
如何处理表单intput的内部迭代,没有任何值的changue侦听器?
有一些截图:
action或actionListener on会出现同样的问题
答案 0 :(得分:12)
您的问题与PrimeFaces <p:commandButton>
的行为无关,而是与使用<ui:repeat>
标记时产生隐含的范围问题有关。
首先,让我们离开你的榜样。基本上,你有
<ui:repeat value="#{bean.strings}" var="s">
<h:inputText value="#{s}"/>
</ui:repeat>
支持List<String> strings
。
罪魁祸首在于: value="#{s}"
。 <ui:repeat>
变量s
导出的内容仅在其循环中可见,而未绑定到任何托管bean的属性,而是仅绑定到局部变量。换句话说,s
并不像人们所期望的那样约束/等于bean.strings[index]
,并且我们知道它不知道它来自何处。所以基本上,你处于单边关系之中:来自bean的值正确地打印在你的输入中,但反过来却没有发生。
解决方法#1:包装类/模型对象
通过为您的类使用包装器对象可以克服这种情况。如果是字符串,它可能是一个'简单的可变字符串',如下所示:
public class MString {
private String string;//getter+setter+constructor
}
在这种情况下,迭代将按预期工作:
<ui:repeat value="#{bean.mstrings}" var="ms">
<h:inputText value="#{ms.string}"/>
</ui:repeat>
支持List<MString> mstrings
。
请注意,如果您拥有模型类,例如User
,并且将在<ui:repeat>
中更改其属性,则类本身将实际上是一个包装器,以便适当地设置属性。
解决方法#2:链式财产访问
另一种解决方法是直接从<h:inputText>
标记中访问您的集合元素。这样,任何此类属性都将通过访问bean,然后集合,然后在所需索引处设置属性来设置。过长,但就是这样。至于问题如何,<ui:repeat>
提供了一个导出的当前迭代状态变量varStatus
,它将用于访问托管bean中的数组/集合。
在这种情况下,迭代也将按预期工作:
<ui:repeat value="#{bean.strings}" var="s" varStatus="status">
<h:inputText value="#{bean.strings[status.index]}"/>
</ui:repeat>
使用普通支持List<String> strings
。
答案 1 :(得分:2)
我的解决方法解决方案直接从页面中获取值:
<ui:repeat id="repeat" value="#{bean.strings}" var="s" varStatus="status">
<h:inputText id="x" value="#{s.field}"/>
<h:commandLink style="margin: .5em 0" styleClass="commandLink" actionListener="#{bean.save(status.index)}" value="#{bundle.Send}"/>
</ui:repeat>
保存方法:
public void save(String rowid) {
String jsParam = Util.getJsParam("repeat:" + rowid + ":x");
System.out.println("jsParam: " + jsParam); //persist...
}
getJsParam方法:
public static String getJsParam(String paramName) {
javax.faces.context.FacesContext jsf = javax.faces.context.FacesContext.getCurrentInstance();
Map<String, String> requestParameterMap = jsf.getExternalContext().getRequestParameterMap();
String paramValue = requestParameterMap.get(paramName);
if (paramValue != null) {
paramValue = paramValue.trim();
if (paramValue.length() == 0) {
paramValue = null;
}
}
return paramValue;
}