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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 06:10:32