Primefaces 8 DataTable单元格编辑提交错误数据求助
解决方案
问题根源
核心问题在于ListDataModel的实例重复创建、Bean作用域不当,以及JSF生命周期中getModel()被多次调用导致视图与后台数据实例不一致,最终引发编辑值丢失、表格混乱。
具体修复步骤
1. 修正Bean作用域与数据初始化逻辑
将Bean改为@ViewScoped(确保视图生命周期内数据稳定),并把数据加载移到初始化方法中,避免getModel()重复创建模型实例:
@ManagedBean @ViewScoped public class CostingOverviewBean implements Serializable { private List<KontenrahmenIstkosten> list; private DataModel<KontenrahmenIstkosten> model; private NumberConverter converter; @PostConstruct public void init() throws IOException { load_Strukturplan(); model = new ListDataModel<>(list); converter = new NumberConverter(); } // 直接返回已初始化的model,不再重复创建 public DataModel<KontenrahmenIstkosten> getModel() { return model; } // 手动刷新数据的方法(按需调用) public void refreshData() throws IOException { load_Strukturplan(); model = new ListDataModel<>(list); } public void onCellEdit(CellEditEvent event) throws IOException { KontenrahmenIstkosten editedItem = (KontenrahmenIstkosten) event.getObject(); System.out.println("新值: " + event.getNewValue()); System.out.println("行ID: " + event.getRowKey()); // 同步视图 PrimeFaces.current().ajax().update("form:costingOverviewData"); } private void load_Strukturplan() throws IOException { // 原数据加载逻辑,填充list集合 } // 其他业务方法... }
2. 优化DataTable的Ajax配置
调整p:ajax的process和update属性,确保表单数据被正确处理、视图同步:
<p:dataTable style="transform: scale(1); transform-origin: 0 0;" id="costingOverviewData" value="#{costingOverviewBean.model}" var="item" editable="true" editMode="cell" selectionMode="single" disabledSelection="true" rowStyleClass="#{(item.konto % 1000) eq 999 ? 'total':null}" rowKey="#{item.ID}"> <!-- 扩展处理范围,确保编辑数据被正确提交,并更新表格视图 --> <p:ajax event="cellEdit" listener="#{costingOverviewBean.onCellEdit}" process="@form" update="costingOverviewData" /> <p:column rendered="#{costingOverviewBean.showVorkalk ne false}" style="min-width: 20px;width:20px; max-width: 20px;"> <h:outputText value="#{item.konto}" /> </p:column> <p:column style="min-width: 200px;width:200px; max-width: 200px;"> <h:outputText value="#{item.beschreibung}" /> </p:column> <p:column rendered="#{costingOverviewBean.showVorkalk eq true}" width="75" headerText="#{res['COV_VorkalkQuantity']}" style="text-align:right"> <p:cellEditor> <f:facet name="output"> <p:outputPanel style="#{item.menge_Vorkalk ne null ? 'border-style:solid;border-color:grey;border-width:0.5pt':'border-style:none'}"> <p:outputLabel value="#{item.menge_Vorkalk}"> <f:convertNumber integerOnly="true"></f:convertNumber> </p:outputLabel> </p:outputPanel> </f:facet> <f:facet name="input"> <p:inputNumber rendered="#{item.menge_Vorkalk ne null}" id="menge_Vorkalk_Input" value="#{item.menge_Vorkalk}" style="width:96%"> </p:inputNumber> </f:facet> </p:cellEditor> </p:column> </p:dataTable>
3. 关键逻辑说明
- ViewScoped作用域:保证Bean在当前视图的整个生命周期内唯一,避免每次请求重建导致数据丢失。
- 简化getModel():不再在getter中初始化模型,因为JSF会多次调用getter,重复创建
ListDataModel会导致视图绑定的实例与后台处理实例不一致。 - Ajax配置优化:
process="@form"确保编辑的表单数据被完整提交,update="costingOverviewData"强制刷新表格,让视图与后台数据同步。
内容的提问来源于stack exchange,提问作者jsfnewbie
相关产品推荐
相关产品推荐

