按下按钮时只需要获取选定的行即可跳过p:dataTable内部的输入组件处理 [英] Skip processing of input components inside p:dataTable when a button is pressed which only needs to get selected rows

查看:54
本文介绍了按下按钮时只需要获取选定的行即可跳过p:dataTable内部的输入组件处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我仅准备了一个简单的购物篮示例,仅用于演示目的.

XHTML页面:

<p:dataTable id="cartDataTable" value="#{testManagedBean.qtyList}"
             var="cart"
             selection="#{testManagedBean.selectedQtyList}"
             rowKey="#{cart.id}">

    <p:column selectionMode="multiple" />

    <p:column>
        <h:outputText value="#{cart.id}"/>
    </p:column>

    <p:column>
        <p:inputText value="#{cart.qty}"/>
    </p:column>
</p:dataTable>

<p:commandButton value="Delete" process="@this cartDataTable"
                 actionListener="#{testManagedBean.delete}"/>

托管bean:

@ManagedBean
@SessionScoped
public final class TestManagedBean implements Serializable
{
    private List<Cart>qtyList; //Getter only.
    private List<Cart>selectedQtyList; //Getter and setter.
    private static final long serialVersionUID = 1L;

    @PostConstruct
    public void init()
    {
        qtyList=new ArrayList<>();
        qtyList.add(new Cart(1, 1));
        qtyList.add(new Cart(2, 1));
        qtyList.add(new Cart(3, 2));
        qtyList.add(new Cart(4, 1));
        qtyList.add(new Cart(5, 3));
    }

    public void delete()
    {
        for(Cart cart:selectedQtyList) {
            System.out.println(cart.getId()+" : "+cart.getQty());
        }

        System.out.println("Perform deletion somehow.");
    }
}

这是一个会话范围内的JSF托管的bean,其中包含购物车. Cart类非常直观,只有两个Integer类型的属性,即idqty和一个参数化构造函数.

单击给定的删除按钮时,我们需要将要删除的选定行设置为支持bean.

要设置选定的行,将<p:commandButton>process属性设置为@thiscartDataTable,当按下此按钮时,该属性会将选定的行设置为bean的属性selectedQtyList.

由于这是一个会话范围的Bean,如果用户不知道在按下Delete按钮之前在任何行中修改了购物车中的数量,则会将新的数量值设置为列表qtyList. /p>

只有在更新购物车时才会发生这种情况,但删除行时肯定不再发生这种情况.

在实际应用程序中,删除是在单独的视图作用域bean中完成的.

如果<p:commandButton>process属性仅设置为@this(即process="@this"从该属性中删除cartDataTable),则选定的行未设置为托管Bean属性selectedQtyList. /p>

如何进行此操作?

解决方案

据我了解,您基本上希望防止在按下Delete按钮时对<p:inputText value="#{cart.qty}">进行处理(更新模型值).从理论上讲,应该只在process属性中指定选择列,但不幸的是<p:dataTable>并没有这么做.另外,按钮上的immediate="true"也无济于事,因为<p:column selectionMode>不支持该功能.

您最好的选择是确保输入字段的rendered属性仅在未按下删除按钮或JSF呈现响应时才对true求值.

<p:inputText ... rendered="#{empty param[delete.clientId] or facesContext.renderResponse}" />
...
<p:commandButton binding="#{delete}" ... />

JSF不会处理未渲染的输入组件.在这种情况下,bean范围无关.

I have prepared just a simple example of shopping basket for the demonstration purpose only.

The XHTML page:

<p:dataTable id="cartDataTable" value="#{testManagedBean.qtyList}"
             var="cart"
             selection="#{testManagedBean.selectedQtyList}"
             rowKey="#{cart.id}">

    <p:column selectionMode="multiple" />

    <p:column>
        <h:outputText value="#{cart.id}"/>
    </p:column>

    <p:column>
        <p:inputText value="#{cart.qty}"/>
    </p:column>
</p:dataTable>

<p:commandButton value="Delete" process="@this cartDataTable"
                 actionListener="#{testManagedBean.delete}"/>

The managed bean:

@ManagedBean
@SessionScoped
public final class TestManagedBean implements Serializable
{
    private List<Cart>qtyList; //Getter only.
    private List<Cart>selectedQtyList; //Getter and setter.
    private static final long serialVersionUID = 1L;

    @PostConstruct
    public void init()
    {
        qtyList=new ArrayList<>();
        qtyList.add(new Cart(1, 1));
        qtyList.add(new Cart(2, 1));
        qtyList.add(new Cart(3, 2));
        qtyList.add(new Cart(4, 1));
        qtyList.add(new Cart(5, 3));
    }

    public void delete()
    {
        for(Cart cart:selectedQtyList) {
            System.out.println(cart.getId()+" : "+cart.getQty());
        }

        System.out.println("Perform deletion somehow.");
    }
}

This is a session scoped JSF managed bean holding a shopping cart. The class Cart is quite intuitive with only two properties of type Integer namely id and qty and a parameterized constructor.

When the given delete button is clicked, we need to set the selected rows to be deleted to the backing bean.

To set the selected rows, the process attribute of <p:commandButton> is set to @this and cartDataTable which sets the selected rows to the bean's property selectedQtyList, when this button is pressed.

Since this a session scoped bean, if a user unknowing modifies the quantity in the cart in any row/s prior to pressing the delete button then, new value/s of quantity is/are set to list qtyList.

This should happen only when updating the cart but certainly must not happen anymore while deleting row/s.

In real application, deletion is done in a separate view scoped bean.

If the process attribute of <p:commandButton> is set to @this only (i.e process="@this" removing cartDataTable from this attribute) then, selected rows are not set to the managed bean property selectedQtyList.

How to proceed with this?

解决方案

As far as I understand, you basically want to prevent <p:inputText value="#{cart.qty}"> from being processed (updating the model value) when the delete button is pressed. Theoretically, it should work to only specify the selection column in the process attribute, but unfortunately <p:dataTable> didn't eat that. Also, immediate="true" on the button won't help as the <p:column selectionMode> doesn't support that.

Your best bet is making sure that rendered attribute of the input field only evaluates true if the delete button is not pressed or when JSF is rendering the response.

<p:inputText ... rendered="#{empty param[delete.clientId] or facesContext.renderResponse}" />
...
<p:commandButton binding="#{delete}" ... />

JSF namely won't process input components which aren't rendered. The bean scope is irrelevant in this case.

这篇关于按下按钮时只需要获取选定的行即可跳过p:dataTable内部的输入组件处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆