我有一个DataTable(Primefaces 3.5,JSF 2.0),它是从数据库中填充的。在此表的第一列中,显示了复选框(多行选择)。
选择行后,按下按钮(<p:commandButton>
)时,预计将从数据库中删除所选行。
在删除行之前,<p:confirmDialog>
中显示有关删除所选行的确认消息,其中包含两个按钮是和否类似以下内容。
Test.xhtml:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition template="template/Template.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<ui:define name="title">Test</ui:define>
<ui:define name="content">
<h:form id="form">
<p:dataTable id="dataTable" var="row" value="#{testManagedBean.list}"
selection="#{testManagedBean.selectedValues}"
rowKey="#{row.id}"
rowIndexVar="rowIndex">
<p:column selectionMode="multiple" style="width:5%; text-align: center;">
<f:facet name="footer">
----------------> <p:commandButton actionListener="#{testManagedBean.deleteMultipleActionListener}" oncomplete="confirmDeleteMultiple.show()" update=":form:confirmDialogDeleteMultiple" process=":form:dataTable" icon="ui-icon ui-icon-close"/>
</f:facet>
</p:column>
<p:column headerText="Index">
<h:outputText value="#{rowIndex+1}"/>
</p:column>
<p:column id="id" headerText="Id">
<h:outputText value="#{row.id}"/>
</p:column>
<p:column id="countryName" headerText="Description">
<h:outputText value="#{row.description}"/>
</p:column>
</p:dataTable>
---------------><p:confirmDialog id="confirmDialogDeleteMultiple" widgetVar="confirmDeleteMultiple" appendToBody="true" message="Delete row(s)?" showEffect="true" hideEffect="true" header="Deletion of row." severity="alert" closeOnEscape="true" closable="true">
<p:commandButton id="confirmDeleteMultiple" value="Yes" oncomplete="confirmDeleteMultiple.hide()" actionListener="#{testManagedBean.deleteMultiple}" process="@this dataTable" update="dataTable"/>
<p:commandButton id="declineDeleteMultiple" value="No" onclick="confirmDeleteMultiple.hide()" type="button" />
</p:confirmDialog>
</h:form>
</ui:define>
</ui:composition>
托管bean:
@ManagedBean
@ViewScoped
public final class TestManagedBean implements Serializable
{
@EJB(mappedName="ejb/JNDI")
private TestService testService;
private List<Test> list;
private List<Test>selectedValues;
public TestManagedBean(){}
@PostConstruct
public void init()
{
list=testService.getList();
}
public List<Test> getList() {
return list;
}
public List<Test> getSelectedValues() {
return selectedValues;
}
public void setSelectedValues(List<Test> selectedValues) {
this.selectedValues = selectedValues;
}
public void deleteMultipleActionListener(ActionEvent actionEvent)
{
//Just show a warning message, when the delete button is pressed.
for(Test test:selectedValues)
{
System.out.println(test.getId()+" : "+test.getDescription());
}//Displays the list.
}
public void deleteMultiple(ActionEvent actionEvent)
{
System.out.println("multiple");
for(Test test:selectedValues)
{
System.out.println(test.getId()+" : "+test.getDescription());
}//The list is not null and empty.
}
}
当按下按钮(由XHTML中的箭头指示)时,将调用托管bean中的deleteMultipleActionListener()
方法,只显示由所选行填充的列表。然后出现XHTML中显示的确认对话框。 (这只是为了在删除之前显示警告消息。此方法中的循环仅用于演示)。
当按下确认对话框中的是按钮时,将调用deleteMultiple()
方法,该方法负责实际删除行actionListioner
中的<p:commandButton>
在<p:confirmDialog>
)内部并且应该执行行的删除,但是这里检索的所选行的列表是空的(不为空)。
由于模板页面上的deleteMultiple()
,<f:view>
方法中的结果列表为空。模板页面如下所示。
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="#{localeBean.language}"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
--------->
<f:view locale="#{localeBean.locale}" encoding="UTF-8" contentType="text/html">
<f:loadBundle basename="messages.ResourceBundle" var="messages"/>
<h:head><title><ui:insert name="title">Default Title</ui:insert></title></h:head>
<h:body>
<p:layout fullPage="true">
<p:layoutUnit position="north" size="135" collapsed="false" resizable="false" closable="false" collapsible="false" gutter="6">
<h:form>
<h:selectOneMenu id="languages" value="#{localeBean.language}" onchange="submit();" style="position: absolute; right: 0; top: 50px;">
<f:selectItem itemValue="en" itemLabel="English" />
<f:selectItem itemValue="hi" itemLabel="Hindi" />
</h:selectOneMenu>
</h:form>
</p:layoutUnit>
<p:layoutUnit position="west" id="leftPanel" size="225" header="Menu Item" resizable="false" closable="false" collapsible="true" gutter="6">
</p:layoutUnit>
<p:layoutUnit position="center" size="2500" maxSize="2500">
<ui:insert name="content">Put default content here, if any.</ui:insert>
</p:layoutUnit>
</p:layout>
</h:body>
</f:view>
</html>
当我从上面的Test.xhtml
页面移除此模板并在<f:view>
页面本身上使用此Test.xhtml
标记时,一切正常并且列表正确获取deleteMultiple()
方法中的选定行。
那么,出了什么问题?如果模板页面被<f:view>
括起来,当按下是按钮时,为什么列表变空?这是错的吗?怎么做到这一点? (<f:view>
用于本地化应用程序,因为它可以想象)。
答案 0 :(得分:2)
当您将process="@this datatable"
中的confirmDeleteMultiple
替换为process="@this"
时,问题就解决了,这样只会处理按钮组件。实际上,在发送删除确认时,您不需要Ajax来处理数据表,因为删除的值已经存储在bean中,因为上一步(视图范围的主要好处)。
在Ajax请求中处理数据表再次调用setSelectedValues
setter,因此原始值将被新(空)选择覆盖。