JSF:数据表优先删除方法两次

时间:2016-07-03 10:54:49

标签: ajax jsf primefaces datatable autocomplete

我在我的jsf数据表组件中遇到了一个奇怪的行为,并且无法弄清楚发生了什么。这是场景:我有一个数据表,每行都有一个删除按钮。当我点击最后一行的按钮时,它被正确删除。当我单击最后一行之前的行中的按钮时,它会删除行本身以及下一行。它上面的行没有受到影响。

我的环境:Eclipse Neon + Tomcat 8 + Primefaces 6.0

我从Eclipse内部运行项目。

p:dataTable的数据源正在被从p:autoComplete组件中选择的数据修改。

在debbuging模式下,我可以检查每次使用不同参数多次调用remove方法。贝娄是代码的一部分。

看起来(查看浏览器开发人员工具)Ajax只调用一次服务器方法,因此多次执行发生在服务器端。

我已经在Link 1Link 2等链接中搜索过类似问题。

page.xhtml:

<p:autoComplete id="ddl" dropdown="false"
                value="#{bean.chosenItem}" var="item"
                itemLabel="#{item.name}" itemValue="#{item}"
                converter="convertItem"
                emptyMessage="No item found" queryDelay="1000"
                minQueryLength="3" autocomplete="off"
                completeMethod="#{bean.findItemsCompleteText}"
                forceSelection="true" placeholder="Type item name"
                cache="true" widgetVar="dllWGV">
    <p:ajax event="itemSelect"
            listener="#{bean.addToDataTable}"
            update="dtb ddl" />
</p:autoComplete>

<p:dataTable id="dtb"
             value="#{bean.chosenItems}" var="rowItem"
             sortBy="#{rowItem.name}" scrollable="true" scrollHeight="90"
             scrollWidth="337" tableStyle="#{bean.dtbStyle}"
             widgetVar="dtbWGV">
      <p:column style="border: none; padding-left: 2px;">
          <p:commandButton actionListener="#{bean.removeFromDataTable(rowItem)}"
                         update="dtb"
                         style="margin-right: 2px;" icon="fa fa-trash" />
          <h:outputText value="#{rowItem.name}" />
      </p:column>

      <p:column style="border: none; width: 28%;">
          <p:spinner suffix="%" min="0" max="100" stepFactor="0.25"
                     value="#{rowItem.dAux}" size="5" />
      </p:column>
</p:dataTable>

托管bean (ViewScoped)

private ItemClass chosenItem;
private List<ItemClass> chosenItems;
private String dtbStyle;

//getters and setters with no logic inside
//beyond getting and setting the properties

@PostConstruct
public void init(){
    if (chosenItems == null) {
        chosenItems = new ArrayList<ItemClass>();
    }
    setDtbStyle("visibility: hidden; width: 320px;");
}

//each time, during the multiple executions,
//the parameter localItem has a different value
public void removeFromDataTable(ItemClass localItem) {
    this.chosenItems.remove(localItem);
    if(chosenItems.size() == 0) {
        setDtbStyle("visibility: hidden; width: 320px;");
    }
}

public void addToDataTable(SelectEvent event) {
    this.chosenItems.add(this.chosenItem);
    setDtbStyle("visibility: visible; width: 320px;");
    this.chosenItem = null;
}

感谢有关可能发生的事情的任何线索。

Juliano的

1 个答案:

答案 0 :(得分:1)

在阅读herehere后,我尝试将process="@this"放在p:dataTable中的remove p:commandButton上。它已成功,但我不知道如何。我已经知道@this告诉服务器只处理p:commandButton的actionLinstener中的方法,忽略页面其他组件中的任何其他操作。好吧,这个修改工作的事实表明问题在于我的页面的整体逻辑。实际上,我不知道我的错误到底在哪里,但由于页面非常沉重,我几乎可以肯定我的某个地方确实存在一个愚蠢的错误。

[1]:Clicking p:commandButton causes the value of p:selectOneMenu being set twice
[2]:Understanding process and update attributes of PrimeFaces

page.xhtml被修改为:

<p:dataTable id="dtb"
             value="#{bean.chosenItems}" var="rowItem"
             sortBy="#{rowItem.name}" scrollable="true" scrollHeight="90"
             scrollWidth="337" tableStyle="#{bean.dtbStyle}"
             widgetVar="dtbWGV">
      <p:column style="border: none; padding-left: 2px;">
          <p:commandButton actionListener="#{bean.removeFromDataTable(rowItem)}"
                           update="dtb" 
                           process="@this" <!--solution: adding this attribute-->
                           style="margin-right: 2px;" icon="fa fa-trash" />
          <h:outputText value="#{rowItem.name}" />
      </p:column>

      <p:column style="border: none; width: 28%;">
          <p:spinner suffix="%" min="0" max="100" stepFactor="0.25"
                     value="#{rowItem.dAux}" size="5" />
      </p:column>
</p:dataTable>