PrimeFaces多DataTable行选择事件异常问题求助
解决方案
问题根源
- 所有动态生成的
p:dataTable都绑定了同一个selectedRow变量,导致只有最后一个表格的选择状态能被正确保留,其他表格选择时该变量会被覆盖或未正确赋值,引发空指针异常。 - 所有表格的
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
相关产品推荐
相关产品推荐

