Angular响应式表单:表格行编辑时如何预填输入框的公司名称
核心问题修正
你当前的实现存在两个关键问题,导致编辑态无法自动预填公司名称:
- 全局仅定义1个
frmFirm表单组、1个firmName控件,所有编辑行的输入框都绑定同一个控件,既无法区分不同行的编辑值,也没法匹配对应行的预填数据 - 点击编辑按钮的交互逻辑中,完全没有触发表单控件的赋值操作
分步修正实现
1. 调整组件类的表单结构
将原来的单一表单组替换为FormArray结构,数据加载时就为每一行公司数据生成独立的表单控件,控件初始值直接取当前行的公司名称,从根源实现输入框的预填能力:
import { FormArray, FormBuilder, FormGroup } from '@angular/forms'; // 组件类成员定义 frmFirm: FormGroup; Firms: IFirm[] = []; // 保留原有的编辑状态标记逻辑 EditMode: { [id: number]: boolean } = {}; ngOnInit(): void { // 初始化根表单组 this.frmFirm = this._fb.group({ // 表单内部嵌入用于管理所有行编辑状态的FormArray firmList: this._fb.array([]) }); this.getFirms(); } // 封装快速获取FormArray引用的方法 get firmFormArrayControl(): FormArray { return this.frmFirm.get('firmList') as FormArray; } public getFirms() { this.userService.getFirms().subscribe((data: IFirm[]) => { this.Firms = data; // 遍历公司列表,为每一条数据生成独立的表单控件 const firmFormGroups = this.Firms.map(firm => { return this._fb.group({ // 控件初始化时直接绑定当前行的公司名称作为默认值 firmName: [firm.firmName] }) }); // 将生成的所有行表单组挂载到根表单的FormArray上 this.frmFirm.setControl('firmList', this._fb.array(firmFormGroups)); }); } // 编辑触发逻辑仅需切换行的编辑状态即可,预填值已在控件初始化时绑定 editUser(firmId: number) { this.EditMode[firmId] = true; } // 保存逻辑直接从对应行的表单控件中取最新编辑值 saveUser(firmId: number) { // 定位当前操作的行在列表中的索引 const firmIndex = this.Firms.findIndex(f => f.id === firmId); // 取出索引对应控件的最新值 const updatedFirmName = this.firmFormArrayControl.at(firmIndex).get('firmName').value; // 此处接入原有的保存接口逻辑即可 // 保存完成后退出编辑态 this.EditMode[firmId] = false; }
2. 调整HTML模板的表单绑定逻辑
替换原来全局绑定单个控件的写法,改为逐行绑定对应索引的表单控件,避免不同行的输入值串扰:
<form [formGroup]="frmFirm"> <table class="table table-striped"> <thead> <tr> <th style="width: 30%">Firm Name</th> <th style="width: 10%"></th> </tr> </thead> <!-- 绑定FormArray,逐行遍历渲染 --> <tbody formArrayName="firmList"> <tr *ngFor="let firm of Firms; let i = index"> <!-- 非编辑态直接展示纯文本 --> <td *ngIf="!EditMode[firm.id]">{{firm.firmName}}</td> <!-- 编辑态:绑定当前行索引对应的独立表单组 --> <td *ngIf="EditMode[firm.id]" [formGroupName]="i"> <input type="text" formControlName="firmName" class="form-control col-md-3" /> </td> <td *ngIf="EditMode[firm.id]" style="white-space: nowrap"> <button (click)="saveUser(firm.id)" class="btn btn-sm btn-primary mr-1">Save</button> </td> <td *ngIf="!EditMode[firm.id]" style="white-space: nowrap"> <button (click)="editUser(firm.id)" class="btn btn-sm btn-primary mr-1">Edit</button> <button (click)="deleteUser(firm.id)" class="btn btn-sm btn-danger btn-delete-firm" [disabled]="firm.isDeleting"> <span *ngIf="firm.isDeleting" class="spinner-border spinner-border-sm"></span> <span *ngIf="!firm.isDeleting">Delete</span> </button> </td> </tr> <!-- 修正原代码中变量名不匹配的加载判断逻辑 --> <tr *ngIf="!Firms"> <td colspan="4" class="text-center"> <span class="spinner-border spinner-border-lg align-center"></span> </td> </tr> </tbody> </table> </form>
适配说明:修改后支持同时对多行触发编辑态,每一行的输入值独立存储,点击编辑切换到输入态时,控件会自动加载初始化时绑定的公司名称,不需要额外临时赋值操作,完全兼容你原有的编辑状态标记、删除按钮加载等业务逻辑。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

