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

PF6 datatable的rowToggle ajax事件监听器获取到错误的参数值

问题原因

这是PrimeFaces 6版本中<p:dataTable>绑定顶层rowToggle事件的已知行为:你直接在<p:ajax>的listener表达式中传递dataTable的var变量line时,EL表达式会在视图渲染阶段逐行求值并覆盖引用,最终只会保留数据源最后一行的line对象,因此所有行触发事件时都会传递同一个最后一行的参数。
你其他同类AJAX调用可以正常使用var变量,是因为那些AJAX是绑定在每一行的子组件(比如行内按钮、行点击事件)上,上下文和当前行绑定,EL求值发生在事件触发阶段,不会被后续行渲染覆盖。

解决方法

有两种常用的修复方案:

方案1:通过ToggleEvent获取当前行数据(推荐)

rowToggle事件触发时会自动携带ToggleEvent对象,其中直接包含了被操作的行数据和切换状态,不需要主动传参:

  1. 修改前端AJAX配置,去掉listener中的参数:
    <p:ajax event="rowToggle" 
            listener="#{cartController.toggleAndSaveLine}" 
            disabled="#{facesContext.validationFailed}"/>
    
  2. 调整后端方法,从事件中提取参数:
    import org.primefaces.event.ToggleEvent;
    import org.primefaces.model.Visibility;
    
    // 注意替换方法入参的Line类为你实际的行数据实体类型
    public void toggleAndSaveLine(ToggleEvent event) {
        Line currentLine = (Line) event.getData();
        // 获取切换后的状态:true为展开,false为收起
        boolean isExpanded = event.getVisibility() == Visibility.VISIBLE;
        // 后续执行你的保存逻辑即可
    }
    

方案2:将AJAX绑定到rowToggler组件上

把<p:ajax>从dataTable根节点移到每一行的<p:rowToggler>组件内部,让AJAX上下文和当前行绑定,就可以正常传递line参数:

<p:dataTable expandedRow="#{line.toggled}"
             value="#{cartController.getLines(agreement.id)}" 
             var="line" widgetVar="table" rowIndexVar="rowIndex">
  <p:column>
    <p:rowToggler>
      <p:ajax event="toggle" 
              listener="#{cartController.toggleAndSaveLine(line)}" 
              disabled="#{facesContext.validationFailed}"/>
    </p:rowToggler>
  </p:column>
  <!-- 其他列、行展开内容 -->
</p:dataTable>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 11:30:01