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对象,其中直接包含了被操作的行数据和切换状态,不需要主动传参:
- 修改前端AJAX配置,去掉listener中的参数:
<p:ajax event="rowToggle" listener="#{cartController.toggleAndSaveLine}" disabled="#{facesContext.validationFailed}"/> - 调整后端方法,从事件中提取参数:
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
相关产品推荐
相关产品推荐

