commandButton action =“#{bean.delete(row)}”在datatable似乎通过错行 [英] commandButton action="#{bean.delete(row)}" in datatable seems to pass wrong row

查看:116
本文介绍了commandButton action =“#{bean.delete(row)}”在datatable似乎通过错行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个最初填充没有数据(空列表)的数据表。在表的页脚中有一个 commandButton ,可以向表中添加行。当添加行时,行中的最后一个单元格是另一个 commandButton 来删除该行。我的问题是删除按钮不断删除表中的第一行,而不管选择哪一行。



示例:如果我在表中添加3行,并点击第二行最后一个单元格中的删除按钮, action =#{ addAccountBean.deleteFixVendor(dataItem)}将第一行传递给 deleteFixVendor 方法,而不是单击的第二行。我不知道为什么第一行的对象继续传递给删除方法,无论哪个行按钮被点击。



我的JSF代码: p>

 < h:form> 
< f:validateBean disabled =#{!empty param ['disableValidation']}>
< p:panel id =panelheader =添加新帐户>
< p:dataTable var =dataItemvalue =#{addAccountBean.account.vendors}>

< p:column headerText =Vendor>
< p:selectOneMenu value =#{dataItem.vendor}>
< f:selectItems value =#{addAccountBean.menu.fixOption}/>
< / p:selectOneMenu>
< / p:column>

< p:column headerText =每月成本>
< p:inputText value =#{dataItem.cost}/>
< / p:column>

< p:column headerText =成本日期>
< p:calendar value =#{dataItem.CDate}pattern =MM / dd / yyyynavigator =true/>
< / p:column>

< p:column headerText =Delete>
< h:commandButton value =Deleteaction =#{addAccountBean.deleteFixVendor(dataItem)}>
< f:param name =disableValidationvalue =true/>
< / h:commandButton>
< / p:column>

< f:facet name =footer>
< h:commandButton value =添加新供应商action =#{addAccountBean.addFixVendor}>
< f:param name =disableValidationvalue =true/>
< / h:commandButton>
< / f:facet>

< / p:dataTable>
< / p:panel>
< / f:validateBean>
< / h:form>

Bean代码:

  @ManagedBean 
@SessionScoped
public class AddAccountBean implements Serializable {

private AccountData account = new AccountData();

public String addFixVendor(){

account.getVendors()。add(new VendorData());
return;
}

public String deleteFixVendor(VendorData vData){

account.getVendors()。remove(vData);
return;
}

任何建议都不胜感激。

解决方案

发布的代码到目前为止看起来不错。对于这个问题,唯一可行的解​​释是在 VendorData 类中的 equals()方法。 集合#remove() 将删除集合中的第一个项目,该集合中给定的对象 equals() p>

如果您的(基础)实体有一个 id 属性,则应该执行以下操作:

  @Override 
public boolean equals(Object other){
return(other!= null&& getClass()== other.getClass()&& id!= null)
? id.equals(((VendorData)other).id)
:(other == this);
}

@Override
public int hashCode(){
return(id!= null)
? (getClass()。hashCode()+ id.hashCode())
:super.hashCode();
}


I have a datatable that is initially populated with no data (an empty list). There is a commandButton in the footer of the table that adds rows to the table. When a row is added, the last cell in the row is another commandButton to delete the row. My issue is that the delete button keeps deleting the first row in the table regardless of which row is selected.

Example: if I add 3 rows to the table and hit the delete button in the last cell of the second row, action="#{addAccountBean.deleteFixVendor(dataItem)}" passes the first row to the deleteFixVendor method instead of the second row which was clicked. I can't figure out why the object for the first row keeps on getting passed to the delete method regardless of which row button is clicked.

My JSF code:

<h:form>
<f:validateBean disabled="#{!empty param['disableValidation']}" >
<p:panel id="panel" header="Add New Account"  > 
    <p:dataTable var="dataItem" value="#{addAccountBean.account.vendors}" >

        <p:column headerText="Vendor"  >                                
            <p:selectOneMenu value="#{dataItem.vendor}">                
                        <f:selectItems value="#{addAccountBean.menu.fixOption}" />
                    </p:selectOneMenu>
            </p:column>

            <p:column headerText="Monthly Cost"  >
                <p:inputText value="#{dataItem.cost}" />    
            </p:column>

            <p:column headerText="Cost Date"  >
                <p:calendar value="#{dataItem.CDate}" pattern="MM/dd/yyyy" navigator="true" /> 
            </p:column>

            <p:column headerText="Delete" >
            <h:commandButton value="Delete" action="#{addAccountBean.deleteFixVendor(dataItem)}" >
                <f:param name="disableValidation" value="true" />
            </h:commandButton>  
        </p:column> 

        <f:facet name="footer" >
            <h:commandButton value="Add New Vendor" action="#{addAccountBean.addFixVendor}" >
                <f:param name="disableValidation" value="true" />
            </h:commandButton>      
        </f:facet>

    </p:dataTable>          
</p:panel>  
</f:validateBean>
</h:form>

Bean code:

@ManagedBean
@SessionScoped
public class AddAccountBean implements Serializable {

private AccountData account = new AccountData();

public String addFixVendor() {

    account.getVendors().add(new VendorData());                 
    return "";
}

public String deleteFixVendor(VendorData vData) {

    account.getVendors().remove(vData);                         
    return "";                                                          
}

Any suggestions are appreciated.

解决方案

The code posted so far looks fine. The only feasible explanation for this problem is a broken equals() method in the VendorData class. The Collection#remove() will remove the first item in the collection which equals() the given object.

Provided that your (base) entity has an id property, then this should do:

@Override
public boolean equals(Object other) {
    return (other != null && getClass() == other.getClass() && id != null)
        ? id.equals(((VendorData) other).id)
        : (other == this);
}

@Override
public int hashCode() {
    return (id != null) 
        ? (getClass().hashCode() + id.hashCode())
        : super.hashCode();
}

这篇关于commandButton action =“#{bean.delete(row)}”在datatable似乎通过错行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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