如何通过hover/mouseOver事件选中PrimeFaces dataTable行并更新currentItem
方案1:直接传递行对象作为删除方法参数(最稳妥,无需依赖currentItem)
你完全可以不用维护currentItem变量,直接把当前行的#{item}作为参数传入delete方法,彻底规避执行顺序带来的问题:
前端按钮代码修改
<p:commandButton value="Delete" action="#{itemBean.deleteItem(item)}" process="@this" update="table StartButtonForm"/>
后端Bean代码修改
public void deleteItem(Item item) { // 直接用传入的item执行删除逻辑,不需要依赖currentItem unrankedItems.remove(item); // 其余业务逻辑正常编写即可 }
这个方案是行内按钮操作的首选实现,没有额外的Ajax请求开销,也不会出现执行顺序错误。
方案2:实现鼠标悬停更新currentItem
如果确实有业务需求需要悬停就更新currentItem,可以给dataTable添加rowMouseOver事件的Ajax监听:
完整表格代码修改
<p:dataTable id="table" var="item" value="#{itemBean.unrankedItems}" selection="#{itemBean.currentItem}" selectionMode="single" rowKey="#{item.name}" rowSelectMode="add"> <!-- 原有rowSelect监听保留 --> <p:ajax event="rowSelect" listener="#{itemBean.onRowSelect}"/> <!-- 新增行悬停监听,触发时更新currentItem --> <p:ajax event="rowMouseOver" listener="#{itemBean.setCurrentItem(item)}" process="@this"/> <p:column> <h:outputText value="#{item.name}"/> </p:column> <p:column> <p:commandButton value="Delete" actionListener="#{itemBean.deleteItem}" process="@this" update="table StartButtonForm"> <!-- 这里可以去掉setPropertyActionListener,悬停已经完成了currentItem赋值 --> </p:commandButton> </p:column> </p:dataTable>
注意这个方案会在每次鼠标划过行的时候触发Ajax请求,服务端压力会比方案1大很多,除非有特殊业务需求否则不推荐。
方案3:修复原有f:setPropertyActionListener执行顺序问题
你之前遇到的赋值晚于删除逻辑的问题,本质是因为:commandButton的actionListener属性声明的监听器,执行优先级高于嵌套的f:setPropertyActionListener监听器,所以会先跑删除逻辑再给currentItem赋值。
你只需要把删除逻辑从actionListener属性移到action属性上即可,JSF的执行顺序会保证所有ActionListener(包括f:setPropertyActionListener)都执行完成后,再调用action对应的方法:
<p:commandButton value="Delete" action="#{itemBean.deleteItem}" process="@this" update="table StartButtonForm"> <f:setPropertyActionListener value="#{item}" target="#{itemBean.currentItem}"/> </p:commandButton>
你的delete方法无需做任何修改即可正常运行。
内容的提问来源于stack exchange,提问作者EyeSocketPlug
相关产品推荐
相关产品推荐

