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

PrimeFaces多DataTable行选择事件异常问题求助

解决方案

问题根源

  1. 所有动态生成的p:dataTable都绑定了同一个selectedRow变量,导致只有最后一个表格的选择状态能被正确保留,其他表格选择时该变量会被覆盖或未正确赋值,引发空指针异常。
  2. 所有表格的widgetVar值重复(都是tablePerformance),导致前端JS组件冲突,进一步影响事件处理。

具体修改步骤

1. 后台Bean调整

将单个selectedRow变量替换为Map类型,用每个表格对应的companyCode作为key,存储对应表格的选中行:

import javax.faces.event.AjaxBehaviorEvent;
import org.primefaces.component.datatable.DataTable;
import java.util.HashMap;
import java.util.Map;

// 后台Bean中的变量
private Map<String, Performance> selectedRows = new HashMap<>();

// Getter和Setter
public Map<String, Performance> getSelectedRows() {
    return selectedRows;
}

public void setSelectedRows(Map<String, Performance> selectedRows) {
    this.selectedRows = selectedRows;
}

// 修改行选择事件处理方法
public void onRowSelect(AjaxBehaviorEvent event) {
    DataTable sourceTable = (DataTable) event.getSource();
    // 获取当前表格绑定的companyCode
    String companyCode = (String) sourceTable.getAttributes().get("companyCode");
    // 获取当前表格的选中行
    Performance selectedRow = (Performance) sourceTable.getSelection();
    // 将选中行存入Map
    selectedRows.put(companyCode, selectedRow);
    
    // 后续业务逻辑中,通过selectedRows.get(companyCode)获取对应表格的选中行
}

2. 前端代码调整

  • 给每个p:dataTable设置唯一的widgetVar(带上companyCode后缀)
  • 修改selection绑定为Map中对应companyCode的条目
  • 添加f:attribute传递companyCode,供后台事件方法识别来源表格

修改后的前端代码片段:

<c:forEach items="#{azPerformancePrenPubAll.selectedCompanyTemp}" var="companyCode" varStatus="loop">
  <p:accordionPanel id="acc_#{companyCode}" widgetVar="accordionAziendale_#{companyCode}" activeIndex="-1"> 
    <p:tab title="#{azPerformancePrenPubAll.selectedCompanyName.get(loop.index)}">             
       <p:dataTable id="tablePerformance_#{companyCode}" rendered="#{!azPerformancePrenPubAll.isCompanyVisible}"
                    widgetVar="tablePerformance_#{companyCode}" var="performance" value="#{azPerformancePrenotatiPubAll.listPerformances.get(loop.index)}" 
                    styleClass="perfDataTable no-border" rowIndexVar="rowIndex" 
                    selectionMode="single" selection="#{azPerformancePrenPubAll.selectedRows[companyCode]}" rowKey="#{performance.id}">
         <!-- 传递companyCode到后台 -->
         <f:attribute name="companyCode" value="#{companyCode}" />
         <p:ajax event="rowSelect" listener="#{azPerformancePrenPubAll.onRowSelect}" update="formPerformance,pageSubDescription,pageDescription"/>
         <!-- 表格列定义 -->
         ...
       </p:dataTable>
    </p:tab>
  </p:accordionPanel>
</c:forEach>

原理说明

  • 用Map存储每个表格的选中行,确保每个表格的选择状态独立,不会互相覆盖
  • 唯一的widgetVar避免前端PrimeFaces组件实例冲突
  • 通过f:attribute传递标识,后台能精准定位触发事件的表格,正确处理对应选中行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 19:40:06