使用Ajax从DataTable中删除单行

5

我有一个JSF视图,其中在Primefaces DataTable中列出了集合中的项目。最右侧的列包含删除按钮。当单击删除按钮时,它应该进行Ajax调用,从会话变量Cart中删除相应的项目,并在原地更新视图。我希望请求和视图更改尽可能少。

以下是我为此目的编写的代码:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">

<h:head>
    <title>Register user</title>
</h:head>

<h:body>
    <f:view>

        <h:form id="itemsForm">

            <p:outputPanel id="items">
                <p:dataTable value="#{cart.itemList}" var="item">

                    <p:column>
                        <f:facet name="header">
                            <h:outputText value="name" />
                        </f:facet>
                        <h:outputText value="#{item.product.description}" />
                    </p:column>

                    <p:column>
                        <f:facet name="header">
                            <h:outputText value="quantity" />
                        </f:facet>
                        <h:outputText value="#{item.quantity}" />
                    </p:column>

                    <p:column>
                        <f:facet name="header">
                            <h:outputText value="" />
                        </f:facet>
                        <p:commandButton icon="ui-icon-close" title="remove from cart">
                            <p:ajax listener="#{cart.removeItem}"
                                update="form:itemsForm"
                                process="@this" />
                        </p:commandButton>
                    </p:column>

                    <f:facet name="footer">  
                        Total amount: ${cart.totalAmount}
                    </f:facet>
                </p:dataTable>

            </p:outputPanel>
        </h:form>

    </f:view>
</h:body>
</html>

因此,我在Cart.java中编写了以下方法。
public void removeItem() {
        System.out.println("REMOVE REQUEST ARRIVED");
}

然而,当我点击删除按钮时,removeItem方法甚至没有执行。因此我的问题是: 1)我的Ajax调用有什么问题?我应该如何更改我的XHTML? 2)如何在removeItem方法中处理请求并返回响应? 3)如何更新显示总金额的footer?涉及到it技术。
2个回答

19
你可以在 actionListener 中将 #{item} 作为方法调用的参数传递。
你的 .xhtml 页面应该像这样:
<p:dataTable id="cartTable" value="#{cart.itemList}" var="item">
   <p:column>
      <f:facet name="header">
         <h:outputText value="" />
      </f:facet>
      <p:commandButton icon="ui-icon-close" title="remove from cart"
                       actionListener="#{cart.removeItem(item)}" update="cartTable" />
   </p:column>
</p:dataTable>

这是您的ManagedBeanremoveItem方法:

@ManagedBean
@ViewScoped
public class Cart {
   private List<Item> itemList;

   public void removeItem(Item item) {
      itemList.remove(item);
   }
}

那个不起作用。@ViewScoped注释引发了异常。当我将其更改为@SessionScoped时,按钮没有响应。单击时什么也不会发生。 - Murat Derya Özen
@Murat 我只是试图提供一个例子,让你可以直接使用 #{item} 作为参数,而不必使用 <f:setPropertyActionListener>。你肯定需要将我的例子转换为你自己的用例。我无法猜测你需要什么来给你一个100%的工作解决方案。 - Mr.J4mes
除了actionListener属性应该是action,对吗? - Murat Derya Özen
@Murat 不必要。由于您打算进行Ajax调用而无需进行任何导航,因此可以使用actionListener - Mr.J4mes
2
@ViewScoped 是这样一个 bean 的唯一正确注释。也许你只需要阅读异常并相应地修复它,而不是完全忽略它?我敢打赌它是一个NotSerializableException,这是相当自我解释的。 - BalusC
为了仅处理删除按钮,请添加 process="@this"。请参见 https://dev59.com/-F8e5IYBdhLWcg3w0NCO - Jasper de Vries

2

1) 默认情况下,<p:commandButton 使用 ajax ,因此不要使用 p:ajax , 而应该使用 actionactionListener

2) 我会使用按钮的 action 并返回 null

3) update="@form" 应该更新整个表单,这将更新整个表格。

这里有一个有效的按钮(链接)示例来自我的页面,我使用了 f:setPropertyActionListener 来向删除方法“传递”一些数据。

<p:commandButton action="#{cart.removeItem}" icon="ui-icon-close" title="remove from cart" update="@form" process="@this" >
      <f:setPropertyActionListener
             target="#{cart.selectedItem}"
             value="#{item}" />
</p:commandButton>

在你的类中添加以下内容:
private Item selectedItem;

public Item getSelectedItem() {
    return selectedItem;
}


public void setSelectedItem(Item selectedItem) {
    this.selectedItem = selectedItem;
}

谢谢您的答复。那么,您代码中的hoursReportBean对应于我拥有的Cart类吗?您如何获取所选项目?那里的value参数是什么?我对所有这些都很陌生。 - Murat Derya Özen
我更新了我的答案的公告(1),是关于Cart类的,所选项目是使用selectedHourReportsToDeleteFromTable设置的,它只是类中getter/seter类型为“item”的属性,因此在单击按钮执行之前,通过setPropertyActionListener进行设置,然后在删除方法中可以使用它。 - Daniel
这真让我抓狂。JSF不应该那么难。它不起作用。GET请求已经发送了,但方法没有执行... - Murat Derya Özen
不客气,您添加了哪些修改(可能对其他成员有用)? - Daniel
1
这是对我有效的代码。给表格和页脚分配了id。<p:commandButton action="#{cart.removeItem(item)}" ajax="true" update="itemTable totalAmount" process="@this" onerror="" icon="ui-icon-close" title="从篮子中移除"></p:commandButton> - Murat Derya Özen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接