You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PrimeFaces删除行后无法自动刷新p:dataTable的问题排查

问题:PrimeFaces dataTable删除玩家后无法自动刷新表格

我用p:dataTable展示玩家列表,其中一列的p:commandButton触发p:confirmDialog确认删除操作。目前删除功能正常,但表格始终无法自动刷新。

相关代码

XHTML代码

<h:form id="form" >
   <p:growl/>
     <div class="bloco">
       <h2>PLAYERS</h2>

         <p:dataTable value="#{adminPlayersBean.players}" var="p"
                      paginator="true" paginatorAlwaysVisible="true"
                      paginatorPosition="bottom" rows="8">
<!-- 其他列 -->

          <p:column headerText="X">
            <p:commandButton action="#{adminPlayersBean.remove(p)}" 
                             update="@form" immediate="true" 
                             styleClass="ui-button-danger" icon="pi pi-times">
            <p:confirm header="Delete player" message="Delete #{p.getNickname()}?" />
          </p:commandButton>
        </p:column>

<!-- ... -->

     <p:confirmDialog global="true" showEffect="fade" hideEffect="fade" 
                      responsive="true" width="430" >
                 
        <p:commandButton value="✓ Yes" type="button" styleClass="ui-confirmdialog-yes"/>
        <p:commandButton value="X No" type="button" styleClass="ui-confirmdialog-no" />
     </p:confirmDialog>

<!--... -->

Bean代码

@Named
@ViewScoped
public class AdminPlayersBean implements Serializable {

    private List<Player> players;

    public void remove(Player player) {
        playerController.remove(player);  //从数据库删除玩家
        
        this.players = playersController.findAll(); //更新填充dataTable的列表

        PrimeFaces.current().ajax().update(":form");       
    }
}

我已经尝试过这些修改,但都无效:

  • 修改xhtml中commandButton的update属性为:form、@form,给dataTable加id后用:form:table
  • 在Bean中调用PrimeFaces.current().ajax().update(":form")或@form

解决方案

问题核心在全局确认对话框的按钮配置:你当前的确认按钮是type="button",这只是客户端按钮,不会触发服务器端的删除逻辑和表格刷新。而且immediate="true"可能跳过了JSF生命周期的更新阶段,导致表格数据无法重新渲染。

具体修改步骤

  1. 调整删除按钮的职责:让它只负责触发确认框,移除action、update和immediate属性
<p:commandButton styleClass="ui-button-danger" icon="pi pi-times">
    <p:confirm header="Delete player" message="Delete #{p.getNickname()}?" />
</p:commandButton>
  1. 给确认对话框的确认按钮绑定服务器端逻辑:把删除操作和表格更新移到确认按钮上,去掉type="button"(默认是submit类型,会触发AJAX请求)
<p:confirmDialog global="true" showEffect="fade" hideEffect="fade" 
                 responsive="true" width="430">
    <p:commandButton value="✓ Yes" styleClass="ui-confirmdialog-yes" 
                     action="#{adminPlayersBean.remove(p)}" update="@form" />
    <p:commandButton value="X No" styleClass="ui-confirmdialog-no" />
</p:confirmDialog>
  1. 清理Bean中的冗余代码:移除PrimeFaces.current().ajax().update(":form");,因为确认按钮的update="@form"已经会处理表格刷新

另一种更灵活的实现(用远程命令传递参数)

如果需要更清晰的参数传递,可以用p:remoteCommand:

<!-- 在form内添加远程命令 -->
<p:remoteCommand name="deletePlayer" action="#{adminPlayersBean.removeSelected}" update="@form" />

<!-- 修改删除按钮的确认逻辑 -->
<p:commandButton styleClass="ui-button-danger" icon="pi pi-times">
    <p:confirm header="Delete player" message="Delete #{p.getNickname()}?" 
               onConfirm="deletePlayer([{name:'playerId', value:'#{p.id}'}])" />
</p:commandButton>

然后在Bean中添加对应的处理方法:

public void removeSelected() {
    Long playerId = Long.valueOf(FacesContext.getCurrentInstance()
        .getExternalContext().getRequestParameterMap().get("playerId"));
    Player player = playerController.findById(playerId);
    playerController.remove(player);
    this.players = playersController.findAll();
}

内容的提问来源于stack exchange,提问作者Maria

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 15:05:16