我正在尝试在Primefaces数据表中添加一个新行,然后我想提交此表的内容并执行一些业务逻辑 . 数据表模型是在ViewScoped托管bean中维护的集合 .
我正在使用带有Primefaces 3.3的JSF 2.1 .
简短的例子:
<h:form id="my-form">
<p:dataTable value="#{testBean.list}" var="s" id="datatable">
<p:column>
<h:inputText value="#{s}"/>
</p:column>
<f:facet name="footer">
<p:commandButton value="Add row" action="#{testBean.addRow()}" process="@form" update="@form" immediate="true" />
<p:commandButton value="Do stuff" action="#{testBean.doSomeLogic()}" process="@form" update="@form"/>
</f:facet>
</p:dataTable>
</h:form>
托管Bean:
@ManagedBean
@ViewScoped
public class TestBean implements Serializable {
private List<String> list;
public TestBean() {
}
@PostConstruct
public void init() {
list = new ArrayList<String>();
list.add("one");
list.add("two");
}
public void addRow(){
list.add(new String());
}
public void doSomeLogic(){
for (String string : list) {
System.out.println(string);
}
}
// getters and setters
}
实际发生了什么:
-
用户单击"add row"按钮,添加了一个新行(我需要立即生效,因此不进行验证,这些字段是更大表单的一部分) .
-
用户单击"do stuff",该集合具有正确的大小(具有新行)但未考虑用户的输入(既不修改预先退出的行,也不修改新添加的行中的新值) .
我还能做些什么来提交新值?我只是开始JSF而且我不确定我已经100%得到它 .
谢谢你的帮助 .
可能重复:
由于Jitesh, Edit: 问题得以解决,可以在这里找到一个工作示例:JSF2, can I add JSF components dynamically?
2 回答
唯一的问题是你在inputText中使用不可变对象 . 要理解这个退房BaluC's Answer
根据它“作为一个不可变对象,String没有setter方法 . 将永远无法设置输入的值 . ”
尝试从commandButton中删除immediate属性,你会发现在插入每一行时数据将被清除 .
如果我理解正确,表单中的其他地方有一些验证失败 . 当任何提交的表单值未通过验证时,除非使用
immediate
,否则所有提交的值都不会应用于托管bean . 这就是为什么您似乎可以添加新行但不能使用doStuff
方法 . 您没有将immediate
添加到doStuff
.但是说明有一些事情你可以做得更干净,更有效率 .
首先,
action
属性应该真正用于导航操作 . JSF期望绑定到action
的方法具有表示导航结果的返回值 . 对于void
方法,最好使用actionListener
. 有关action
和actionListener
之间区别的更多信息,请阅读:Differences between action and actionListener其次,为什么不将
process
和update
仅设置为数据表组件,然后您不必担心其他表单验证?这是一个例子: