可编辑DataTable中获取selectOneMenu选中项对应行rowkeyId的方法
核心逻辑:渲染selectOneMenu的Ajax事件时,DataTable的行迭代变量var处于当前请求作用域内,直接把对应行的rowKeyId作为参数绑定到事件上即可,不需要额外遍历组件树找行上下文。
实现步骤
1. 前端XHTML代码示例(以PrimeFaces组件为例,原生JSF/MyFaces逻辑通用)
DataTable必须先正确配置var(行遍历变量名)和rowKey属性:
<p:dataTable id="editableTable" value="#{dataBizBean.tableDataList}" var="rowData" rowKey="#{rowData.rowkeyId}" editable="true"> <!-- 其余业务列省略 --> <p:column headerText="选项列"> <p:selectOneMenu value="#{rowData.selectedOption}"> <f:selectItems value="#{dataBizBean.selectOptions}" var="opt" itemLabel="#{opt.optionName}" itemValue="#{opt.optionId}"/> <!-- 绑定选中事件,直接传当前行rowKeyId --> <p:ajax event="itemSelect" listener="#{dataBizBean.onOptionSelect}" process="@this" update="@none"> <!-- 方式1:通过f:attribute隐式传参 --> <f:attribute name="currentRowKey" value="#{rowData.rowkeyId}"/> </p:ajax> </p:selectOneMenu> </p:column> </p:dataTable>
2. 后端Listener两种写法
写法1:配合f:attribute取参,兼容所有JSF版本
public void onOptionSelect(SelectEvent event) { // 直接拿到下拉框选中值 Object selectedValue = event.getObject(); // 从组件属性取当前行rowKeyId UIComponent currentComp = UIComponent.getCurrentComponent(FacesContext.getCurrentInstance()); Long currentRowId = (Long) currentComp.getAttributes().get("currentRowKey"); // 后续直接写业务逻辑即可,两个值都已拿到 }
写法2:方法形参直接传值(写法更简洁)
把前端p:ajax的listener属性改成直接传参,去掉f:attribute配置:
<p:ajax event="itemSelect" listener="#{dataBizBean.onOptionSelect(rowData.rowkeyId)}" process="@this" update="@none"/>
对应后端方法:
public void onOptionSelect(Long currentRowId) { // 选中值已经在JSF更新模型阶段赋值到行对象上,直接根据rowId从列表取对应行数据就能拿到 // 示例:tableDataList是你绑定到DataTable的数据源列表 TableRowBean currentRow = tableDataList.stream() .filter(item -> item.getRowkeyId().equals(currentRowId)) .findFirst() .orElse(null); Object selectedValue = currentRow.getSelectedOption(); // 业务逻辑处理 }
避坑提示
不要在
itemSelect事件触发阶段调用DataTable组件的getRowKey()方法尝试获取行ID,该时机组件尚未完成行状态同步,大概率拿到null或者首行ID。
只要selectOneMenu处于DataTable的列渲染范围内,行遍历变量var就可以在Ajax标签内直接访问,不需要额外引入标签或者配置。
内容的提问来源于stack exchange,提问作者Shubha
相关产品推荐
相关产品推荐

