JSF2:将对象从列表(dataGrid)传递给commandButton的操作方法



如何将对象传递给commandButton的操作方法?我使用的数据表是复合组件的基础。复合组件应该提供交换添加到数据表行中的按钮的可能性。我想我可以用facets实现这一点,但我在将对象从数据表列表传递到操作方法时遇到了问题,既不是直接通过EL,也不是通过属性操作监听器。

视图:

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:customer="http://java.sun.com/jsf/composite/components/customer">
<ui:composition template="/WEB-INF/templates/template.xhtml">
<ui:define name="content">
<h:form id="customerList">
<customer:list list="#{customerControllerBean.list}">
<f:facet name="rowButton">
<h:commandButton value="#{msg.deleteButtonLabel}"
action="#{customerControllerBean.delete(customer)}" />
<h:commandButton value="#{msg.deleteButtonLabel}" action="#{customerControllerBean.deleteCustomer}">
<f:setPropertyActionListener target="#{customerControllerBean.customer}" value="#{customer}"/>
</h:commandButton>
<h:button outcome="customerdetail.jsf?id=#{customer.id}"
value="#{msg.editButtonLabel}" />
</f:facet>
</customer:list>
</h:form>
</ui:define>
</ui:composition>
</html>

使用以下复合组件customer:list:

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface>
<composite:attribute name="list" />
<composite:facet name="rowButton" />
</composite:interface>
<composite:implementation>
<p:dataTable id="customer" var="customer" value="#{cc.attrs.list}">
...
<p:column>
<composite:renderFacet name="rowButton" />
</p:column>
</p:dataTable>
</composite:implementation>
</html>

支持豆:

@Named
@ConversationScoped
public class CustomerControllerBean implements Serializable {
private static final long serialVersionUID = 6168621124401208753L;
List<Customer> allCustomers = null;
private Customer customer;
// setters and getters ...
@PostConstruct
public void loadAllCustomers() {
// load customers
}
public List<Customer> getList() {
return allCustomers;
}
public String delete(Customer customer) {
// delete customer...
return "deleted";
}
public String deleteCustomer() {
// delete customer...
return "deleted";
}

在这种情况下,是否不可能将对象传递给方法?

由于您使用的是Primefaces,所以您可以利用它的数据表功能(如属性和事件)来设置您的模型。

使用Primefaces的DataTable功能

在您的控制器中,您可以指定模型和要对其执行的操作,在本例中,我使用了EJB作为示例。

@ManagedBean
@ViewScoped
public class CustomerBean 
{
private Customer model;
@EJB
private CustomerService cs;
public void rowSelected()
{
// log or do stuff
}
public void delete()
{
cs.delete(model);
}
// getters & setters
}

然后在数据表中指定selectionModeselection属性,并将selection映射到模型。

<p:dataTable id="dtModel" var="row" value="#{bean.list}" selectionMode="single" selection="#{bean.model}">
<p:ajax event="rowSelect" process="@this" listener="#{bean.rowSelected}" update=":content" />
</p:datatable>

在这种情况下,我在p:ajax标记中使用了一个监听器,但这只是一个示例,如果您希望在选择模型后对其进行处理,但不需要设置模型,那么它可能会很有用。您的模型将使用bean的setter方法进行设置。

通过行作为参数

在控制器中,指定将模型作为参数接收的方法。

@ManagedBean
@ViewScoped
public class CustomerBean 
{
@EJB
private CustomerService cs;
public void delete(Customer candidate)
{
cs.delete(candidate);
}
// getters & setters
}

在数据表中,使用var属性中指定的row对象。

<p:dataTable id="dtModel" var="row" value="#{bean.list}">
<p:column headerText="name">
<h:outputText value="#{row.name}" />
</p:column>
<p:column headerText="delete">
<p:commandButton value="delete" actionListener="#{bean.delete(row)}" />
</p:column> 
</p:datatable>

我更喜欢使用第一个示例,因为它允许您通过选择一行,然后对其执行各种操作来设置模型,如删除、编辑或查看其详细信息。您可以通过检查是否选择了型号等来启用或禁用UI上的按钮

提示

您可以使用简单的Facelets模板来创建一个简单的taglib,而不是Composite Components。它们通常工作良好,唯一的缺点是不能强制使用这些组件的接口。

您也可以查看PrimeFaces展示,其中有很多有用的示例。

我希望它能有所帮助。

最新更新