Angular表格编辑异常:取消编辑后数据仍被修改
问题解决:PrimeNG表格行编辑取消后数据仍被修改的问题
问题分析
你的问题根源确实是双向绑定直接修改了原始数据对象:
- 编辑框输入内容时,
[(ngModel)]="data.value"会实时修改原数组中的data对象,哪怕未点击保存或取消 - 取消编辑时,你尝试用
editedData备份替换原数据,但数组是引用类型,加上定时更新逻辑会保留已修改的对象,导致10秒后数据更新时修改依然存在 - 之前的浅拷贝
[...tableData]仅复制数组引用,内部对象还是原引用,无法解决问题
修复方案
1. 调整表格组件的编辑逻辑,使用独立临时编辑对象
编辑初始化时创建原数据的深拷贝(切断引用关联),编辑时绑定这个临时对象,取消时直接丢弃,保存时再更新原数据:
export class TableComponent { @Input() tableData: IData[] = []; // 存储临时编辑对象,key为数据id editedData: { [s: string]: IData } = {}; constructor(private dataService: DataService) {} onRowEditInit(data: IData) { // 深拷贝原数据,避免引用关联 this.editedData[data.id] = JSON.parse(JSON.stringify(data)); } editRow(data: IData, rowIndex: number) { // 保存时用临时对象替换原数组中的对象 this.tableData[rowIndex] = { ...this.editedData[data.id] }; this.dataService.setData([...this.tableData]); delete this.editedData[data.id]; } onRowEditCancel(data: IData) { // 取消时直接删除临时对象,原数据未被改动无需回写 delete this.editedData[data.id]; } }
2. 修改HTML模板,绑定临时编辑对象而非原数据
在p-cellEditor的输入模板中,绑定editedData[data.id]的属性,避免直接修改原数据:
<div class="container"> <p-table [value]="tableData" dataKey="id" editMode="row" scrollHeight="flex" styleClass="p-datatable-gridlines" [rows]="8" [scrollable]="true" > <ng-template pTemplate="header"> <tr> <th class="time">Time</th> <th class="value">Value</th> <th class="action"></th> </tr> </ng-template> <ng-template pTemplate="body" let-data let-editing="editing" let-ri="rowIndex" > <tr [pEditableRow]="data"> <td class="p-column-title"> <p-cellEditor> <ng-template pTemplate="input"> <input pInputText type="text" [(ngModel)]="editedData[data.id].time" /> </ng-template> <ng-template pTemplate="output"> {{ data.time | date : "yyyy-MM-dd HH:mm:ss" }} </ng-template> </p-cellEditor> </td> <td> <p-cellEditor> <ng-template pTemplate="input"> <input pInputText type="number" [(ngModel)]="editedData[data.id].value" /> </ng-template> <ng-template pTemplate="output"> {{ data.value | number : "1.2-2" }} </ng-template> </p-cellEditor> </td> <td class="action-button"> <div class="flex align-items-center justify-content-center gap-2"> <button *ngIf="!editing" pButton pRipple type="button" (click)="onRowEditInit(data)" pInitEditableRow icon="pi pi-pencil" class="p-button-rounded p-button-text" ></button> <button *ngIf="editing" pButton pRipple (click)="editRow(data, ri)" type="button" pSaveEditableRow icon="pi pi-check" class="p-button-rounded p-button-text p-button-success mr-2" ></button> <button *ngIf="editing" pButton pRipple (click)="onRowEditCancel(data)" type="button" pCancelEditableRow icon="pi pi-times" class="p-button-rounded p-button-text p-button-danger" ></button> </div> </td> </tr> </ng-template> </p-table> </div>
3. 优化数据更新逻辑(可选)
在main.component.ts中,更新数据时生成新数组引用,避免变更检测异常:
addNewData() { const newData: IData = { id: Date.now().toString(), time: new Date(), value: Math.floor(Math.random() * 1000) }; this.data.push(newData); // 过滤最近30分钟的数据 const thirtyMinutesAgo = new Date(Date.now() - 30 * 60 * 1000); this.data = this.data.filter(item => new Date(item.time) >= thirtyMinutesAgo); this.dataService.setData([...this.data]); this.latestValue = newData.value; }
关键修复点
- 编辑时绑定临时深拷贝对象,避免实时修改原数据
- 取消编辑时直接丢弃临时对象,无需回写原数据
- 保存时才将临时对象的值同步到原数组,并触发数据服务更新
内容的提问来源于stack exchange,提问作者krk5570
相关产品推荐
相关产品推荐

