如何将可编辑Mat Table数据源与表单绑定?支持模板/响应式表单
我来帮你搞定这个问题!把Mat Table和表单绑定实现行内编辑其实挺直观的,下面我分别给你讲响应式表单和模板驱动表单的具体实现方式,代码示例都给你整理好了,你可以直接参考~
方案一:响应式表单(Reactive Forms)
响应式表单更适合动态表格这种场景,因为它能更灵活地控制表单状态和验证,步骤如下:
1. 导入必要模块
首先在你的模块里导入响应式表单和Mat Table相关模块:
import { ReactiveFormsModule } from '@angular/forms'; import { MatTableModule } from '@angular/material/table'; import { MatInputModule } from '@angular/material/input'; @NgModule({ imports: [ // 其他模块 ReactiveFormsModule, MatTableModule, MatInputModule ] }) export class YourModule { }
2. 定义数据模型与表单数组
在组件类里,先定义数据接口,然后创建FormArray来管理表格的每一行表单:
import { Component } from '@angular/core'; import { FormBuilder, FormArray, FormGroup } from '@angular/forms'; // 定义你的数据模型 interface TableData { id: number; name: string; age: number; } @Component({ selector: 'app-table-form', templateUrl: './table-form.component.html' }) export class TableFormComponent { // Mat Table 列定义 displayedColumns: string[] = ['id', 'name', 'age']; // 数据源数组 dataSource: TableData[] = [ { id: 1, name: '张三', age: 25 }, { id: 2, name: '李四', age: 30 } ]; // 表单数组,每个元素对应一行的FormGroup tableFormArray: FormArray; constructor(private fb: FormBuilder) { // 初始化表单数组,把数据源转成FormGroup this.tableFormArray = this.fb.array( this.dataSource.map(item => this.fb.group({ id: [item.id], name: [item.name], age: [item.age] })) ); } // 获取表单数组的所有FormGroup get formGroups() { return this.tableFormArray.controls as FormGroup[]; } // 提交表单时获取所有数据 onSubmit() { console.log('表单数据:', this.tableFormArray.value); // 这里可以把数据提交到后端或者做其他处理 } }
3. 模板中绑定表单与Mat Table
在HTML模板里,把formArrayName绑定到表格,每一行用formGroupName对应索引,输入框用formControlName绑定字段:
<form [formGroup]="tableFormArray" (ngSubmit)="onSubmit()"> <table mat-table [dataSource]="formGroups" class="mat-elevation-z8"> <!-- ID列 --> <ng-container matColumnDef="id"> <th mat-header-cell *matHeaderCellDef> ID </th> <td mat-cell *matCellDef="let group; let i = index" [formGroupName]="i"> <input matInput formControlName="id" readonly> </td> </ng-container> <!-- 姓名列 --> <ng-container matColumnDef="name"> <th mat-header-cell *matHeaderCellDef> 姓名 </th> <td mat-cell *matCellDef="let group; let i = index" [formGroupName]="i"> <input matInput formControlName="name"> </td> </ng-container> <!-- 年龄列 --> <ng-container matColumnDef="age"> <th mat-header-cell *matHeaderCellDef> 年龄 </th> <td mat-cell *matCellDef="let group; let i = index" [formGroupName]="i"> <input matInput type="number" formControlName="age"> </td> </ng-container> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> </table> <button mat-raised-button color="primary" type="submit">提交表单</button> </form>
方案二:模板驱动表单(Template-Driven Forms)
如果你的需求比较简单,模板驱动表单会更快捷,步骤如下:
1. 导入必要模块
在模块里导入模板驱动表单和Mat Table模块:
import { FormsModule } from '@angular/forms'; import { MatTableModule } from '@angular/material/table'; import { MatInputModule } from '@angular/material/input'; @NgModule({ imports: [ // 其他模块 FormsModule, MatTableModule, MatInputModule ] }) export class YourModule { }
2. 组件类准备数据源
组件里只需要准备可修改的数据源数组即可:
import { Component } from '@angular/core'; interface TableData { id: number; name: string; age: number; } @Component({ selector: 'app-table-form-template', templateUrl: './table-form-template.component.html' }) export class TableFormTemplateComponent { displayedColumns: string[] = ['id', 'name', 'age']; dataSource: TableData[] = [ { id: 1, name: '张三', age: 25 }, { id: 2, name: '李四', age: 30 } ]; onSubmit() { console.log('表单数据:', this.dataSource); // 处理提交逻辑 } }
3. 模板中绑定NgModel
在HTML里,用[(ngModel)]绑定每个输入框到数据源的属性,注意要给每个ngModel设置唯一的name属性:
<form (ngSubmit)="onSubmit()"> <table mat-table [dataSource]="dataSource" class="mat-elevation-z8"> <!-- ID列 --> <ng-container matColumnDef="id"> <th mat-header-cell *matHeaderCellDef> ID </th> <td mat-cell *matCellDef="let item"> <input matInput [(ngModel)]="item.id" name="id-{{item.id}}" readonly> </td> </ng-container> <!-- 姓名列 --> <ng-container matColumnDef="name"> <th mat-header-cell *matHeaderCellDef> 姓名 </th> <td mat-cell *matCellDef="let item"> <input matInput [(ngModel)]="item.name" name="name-{{item.id}}"> </td> </ng-container> <!-- 年龄列 --> <ng-container matColumnDef="age"> <th mat-header-cell *matHeaderCellDef> 年龄 </th> <td mat-cell *matCellDef="let item"> <input matInput type="number" [(ngModel)]="item.age" name="age-{{item.id}}"> </td> </ng-container> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> </table> <button mat-raised-button color="primary" type="submit">提交表单</button> </form>
小提示
- 如果需要实现“点击编辑才显示输入框,否则显示文本”的效果,可以给每一行加一个
isEditing状态,用*ngIf切换显示文本或输入框; - 响应式表单可以轻松添加验证规则,比如在创建
FormGroup时给FormControl加验证器:name: [item.name, Validators.required]; - 模板驱动表单的验证可以用
required等指令直接加在输入框上。
内容的提问来源于stack exchange,提问作者Tracie
相关产品推荐
相关产品推荐

