我在我的jsf数据表组件中遇到了一个奇怪的行为,并且无法弄清楚发生了什么。这是场景:我有一个数据表,每行都有一个删除按钮。当我点击最后一行的按钮时,它被正确删除。当我单击最后一行之前的行中的按钮时,它会删除行本身以及下一行。它上面的行没有受到影响。
我的环境:Eclipse Neon + Tomcat 8 + Primefaces 6.0
我从Eclipse内部运行项目。
p:dataTable的数据源正在被从p:autoComplete组件中选择的数据修改。
在debbuging模式下,我可以检查每次使用不同参数多次调用remove方法。贝娄是代码的一部分。
看起来(查看浏览器开发人员工具)Ajax只调用一次服务器方法,因此多次执行发生在服务器端。
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的
答案 0 :(得分:1)
在阅读here和here后,我尝试将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>