我正在基于PrimeFaces的dataGrid组件实现一个典型的购物车。下面是一些示例代码。
一切正常,但是inputText字段导致设置bean属性的次数与页面中有多少元素一样多。因此,如果我将1
放在数据网格中的第一项中,它被设置,但在此之后它被设置为0
N次,从而覆盖它。
我猜这是因为每个inputText都有相同的id。我试图将输入+ commandLink包含在自己的表单中,但这不起作用。我相信这是一个常见的情况,一定有一个优雅的解决方案。
<h:form id="itemsForm" prependId="false">
<p:dataGrid id="itemList" value="#{itemsBean.items}" var="item" type="unordered" paginator="true" rows="12" columns="1">
<p:column>
<p:inputText value="#{cartBean.quantity}"/>
<p:commandLink actionListener="#{cartBean.add}" update=":cartPanel" value="Add to cart">
<f:setPropertyActionListener target="#{cartBean.itemToCart}" value="#{item}"/>
</p:commandLink>
</p:column>
</p:dataGrid>
</h:form>
您可以在这里使用AJAX来完成表单数据的partial submit
*。在这里,我将使用JSF 2.0的内置AJAX支持和标准dataTable
给出一个示例,但JSF 1的想法是一样的。x(使用例如a4j)和dataGrid
:
Facelet:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
>
<h:head/>
<h:body>
<h:form id="form">
<h:dataTable id="table" value="#{singleListSelectBean.items}" var="item">
<h:column>
#{item}
<h:inputText id="input" value="#{singleListSelectBean.value}" />
<f:ajax execute="input">
<h:commandButton value="Select" action="#{singleListSelectBean.select(item)}" />
</f:ajax>
</h:column>
</h:dataTable>
</h:form>
</h:body>
</html>
豆:
@ManagedBean
@ViewScoped
public class SingleListSelectBean {
private List<String> items = Arrays.asList("a", "b", "c");
private String value;
public void select(String item) {
System.out.format("Selecting item %s with value %s.", item, value);
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public List<String> getItems() {
return items;
}
}
这里发生的是<f:ajax>
标记将Ajax功能应用于命令按钮。通过execute
属性告诉它,只有ID为input
的组件的输入应该被处理。
在呈现每个命令按钮的上下文中,ID input
为每行解析为不同的实际client ID
。例如,第一行为form:table:0:input
,第二行为form:table:1:input
,以此类推。通过这种方式,部分提交已经完成,您的后台bean的单值绑定将接收用户单击的那一行的值。
请注意,在给出的示例中,表格不会重新呈现,并且值将"固定"在每个输入文本组件中。这可能会给人一种备份bean绑定到多个值的错觉,但这是而不是的情况。
(*) 虽然从概念上讲我们讨论的是partial submit
,但是JSF的特定实现(例如Mojarra)仍然可以选择发布整个表单并在服务器端进行过滤。