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

如何将可编辑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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:04:02