当表单处于可编辑模式时,我需要在primefaces数据表中包含inputTexts。
一切正常,除了表格清洁,立即=" true" (没有表格验证)。然后,primefaces数据表的行为是不可预测的。在使用新数据填充数据表后 - 它仍然存储旧值。
简短示例 - 显示h:dataTable和p:dataTable - 之间的差异,但当示例中只有三个表中的一个时,它的工作方式相同: test.xhtml
<h:body>
<h:form id="form">
<p:dataTable var="v" value="#{test.list}" id="testTable">
<p:column headerText="Test value">
<p:inputText value="#{v}"/>
</p:column>
</p:dataTable>
<h:dataTable var="v" value="#{test.list}" id="testTable1">
<h:column>
<f:facet name="header">
<h:outputText value="Test value" />
</f:facet>
<p:inputText value="#{v}" />
</h:column>
</h:dataTable>
<p:dataTable var="v" value="#{test.list}" id="testTable2">
<p:column headerText="Test value">
<h:outputText value="#{v}" />
</p:column>
</p:dataTable>
<p:commandButton value="Clear" actionListener="#{test.clear()}" immediate="true" update=":form:testTable :form:testTable1 :form:testTable2"/>
<p:commandButton value="Update" actionListener="#{test.update()}" update=":form:testTable :form:testTable1 :form:testTable2"/>
</h:form>
</h:body>
和java:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
@Named
@ViewScoped
public class Test implements Serializable {
private static final long serialVersionUID = 1L;
private List<String> list;
@PostConstruct
private void init(){
update();
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
public void clear() {
list = new ArrayList<String>();
}
public void update() {
list = new ArrayList<String>();
list.add("Item 1");
list.add("Item 2");
}
}
在上面的示例中,我有3个配置: 1. p:dataTable与p:inputText 2. h:dataTable与p:inputText 3. p:dataTable with h:outputText
和2个按钮:首先清除数据,第二个应用数据
工作流:
尝试更改p:dataTable和h:dataTable
清除列表数据(字符串的数组列表) - 单击&#34;清除&#34;按钮(假设您单击表单上的取消,因为您不想将数据存储到数据库)
加载新数据 - 点击&#34;更新&#34;按钮(假设您正在使用新数据打开新表单)
问题: 为什么p:dataTable与p:inputText仍然存储手动更改的数据,而不是加载的数据? 有没有办法强制p:dataTable在这种情况下表现得像h:dataTable?
答案 0 :(得分:5)
解决方案是: primefaces resetInput
在我的例子中,它将是:
<p:commandButton value="Clear" actionListener="#{test.clear()}" immediate="true"
update=":form:testTable :form:testTable1 :form:testTable2">
<p:resetInput target=":form:testTable" />
</p:commandButton>
修改强>
在某些情况下 - 如果上述方法不起作用 - 请尝试使用primefaces扩展中的一个:
<pe:resetInput for=":form:testTable" />
答案 1 :(得分:2)
您遇到的问题是在提交表单时,正在为表格中此列表绑定的每个数据表(#{test.list}
或<p>
)提交<h>
值。换句话说:
JSF会将testTable
数据表的值绑定到您的#{test.list}
。
JSF会将testTable1
数据表的值绑定到您的#{test.list}
。这些值将替换从testTable
数据表绑定的值,并且数据将丢失。 #{test.list}
将包含testTable1
。
JSF会将testTable2
数据表的值绑定到您的#{test.list}
。自从
这里的值是旧值,这些值将是为#{test.list}
提交的值。
解决此问题的最佳方法是使用单个<p:dataTable>
(或<h>
,具体取决于您的需要)以及托管bean中的一个属性,该属性控制您的表是处于查看还是编辑模式
JSF代码
<h:form id="form">
<p:dataTable var="v" value="#{test.list}" id="testTable">
<p:column headerText="Test value">
<h:outputText value="#{v}" rendered="#{not test.editMode}" />
<p:inputText value="#{v}" rendered="#{test.editMode}" />
</p:column>
</p:dataTable>
<p:commandButton value="Clear" actionListener="#{test.clear()}" immediate="true"
update="testTable" />
<p:commandButton value="Update" actionListener="#{test.update()}"
update="testTable" />
<!-- adding a new button just for testing purposes -->
<p:commandButton value="Submit list" action="#{test.submit}" />
</h:form>
托管Bean代码
//no need of CDI
@ManagedBean
@ViewScoped
public class Test implements Serializable {
private List<String> list;
private boolean editMode = false;
public Test() {
}
@PostConstruct
private void init(){
update();
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
public void clear() {
list = new ArrayList<String>();
}
public void update() {
list = new ArrayList<String>();
list.add("Item 1");
list.add("Item 2");
}
//method for testing purposes
public void submit() {
//in real life web apps, you should log the messages, don't use System.out
System.out.println("Showing actual values of list attribute.");
for(String s : list) {
System.out.println(s);
}
}
}