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

Angular响应式表单动态行Mat Table报错:this.validator is not a function

解决Angular响应式表单嵌套Mat Table时的this.validator is not a function错误

看起来你遇到的问题根源在于表单初始化逻辑混乱,以及没有正确将Mat Table的数据与响应式表单的FormArray绑定起来。我来一步步帮你修正:

错误原因分析

  1. 你在构造函数里已经初始化了包含actualsVolumeData FormArray的formGroup,但在ngOnInit里又重新赋值了formGroup,直接覆盖了之前的表单结构,导致模板里的formArrayName="actualsVolumeData"找不到对应的FormArray控件,引发验证器相关错误。
  2. 你没有把初始的表格数据转换成FormGroup并添加到FormArray中,表单系统无法识别行数据的验证规则。
  3. onAdd方法只修改了MatTableDataSource的数据,没有同步更新FormArray,导致表单和UI数据脱节。

修正后的完整代码

TypeScript部分

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, FormArray, Validators } from '@angular/forms';
import { Router } from '@angular/router';

@Component({
  selector: 'app-your-component',
  templateUrl: './your-component.component.html',
  styleUrls: ['./your-component.component.css']
})
export class YourComponentComponent implements OnInit {
  columnsToDisplay: string[] = ['id', 'code', 'desc'];
  rows: FormArray = this.fb.array([]);
  formGroup: FormGroup = this.fb.group({ 
    actualsVolumeData: this.rows 
  });

  constructor(private router: Router, private fb: FormBuilder) { }

  ngOnInit() {
    // 初始数据
    const initialList = [
      { code: 'one', desc: 'One1', id: 1 },
      { code: 'two', desc: 'Two1', id: 2 },
      { code: 'three', desc: 'Three1', id: 3 },
    ];

    // 将初始数据转换为FormGroup并添加到FormArray
    initialList.forEach(item => {
      this.rows.push(this.createRowForm(item));
    });
  }

  // 创建单行的FormGroup,添加验证规则
  private createRowForm(item: any): FormGroup {
    return this.fb.group({
      id: [item.id], // id设为不可编辑,直接绑定值
      code: [item.code, Validators.required],
      desc: [item.desc, Validators.required]
    });
  }

  onAdd() {
    // 添加新的空白行FormGroup
    const newRowId = this.rows.length + 1;
    this.rows.push(this.createRowForm({ id: newRowId, code: '', desc: '' }));
  }

  onSubmit() {
    if (this.formGroup.valid) {
      // 提交表单数据,this.formGroup.value就是完整的表单数据
      console.log('提交的数据:', this.formGroup.value);
      // 这里添加你的提交逻辑
    }
  }
}

HTML部分

<form [formGroup]="formGroup">
  <button mat-button (click)="onAdd()">Add New Row</button>

  <table mat-table [dataSource]="rows.controls" formArrayName="actualsVolumeData" class="mat-elevation-z8">
    <!-- ID列 -->
    <ng-container matColumnDef="id">
      <th mat-header-cell *matHeaderCellDef> ID </th>
      <td mat-cell *matCellDef="let row; let i = index" [formGroupName]="i">
        {{ row.get('id')?.value }}
      </td>
    </ng-container>

    <!-- Code列(可编辑+验证) -->
    <ng-container matColumnDef="code">
      <th mat-header-cell *matHeaderCellDef> Code </th>
      <td mat-cell *matCellDef="let row; let i = index" [formGroupName]="i">
        <mat-form-field appearance="fill">
          <input matInput formControlName="code" placeholder="Enter Code">
          <mat-error *ngIf="row.get('code')?.invalid && row.get('code')?.touched">
            Code is required
          </mat-error>
        </mat-form-field>
      </td>
    </ng-container>

    <!-- Description列(可编辑+验证) -->
    <ng-container matColumnDef="desc">
      <th mat-header-cell *matHeaderCellDef> Description </th>
      <td mat-cell *matCellDef="let row; let i = index" [formGroupName]="i">
        <mat-form-field appearance="fill">
          <input matInput formControlName="desc" placeholder="Enter Description">
          <mat-error *ngIf="row.get('desc')?.invalid && row.get('desc')?.touched">
            Description is required
          </mat-error>
        </mat-form-field>
      </td>
    </ng-container>

    <tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
    <tr mat-row *matRowDef="let row; columns: columnsToDisplay;"></tr>
  </table>

  <button mat-button [disabled]="!formGroup.valid" (click)="onSubmit()">Submit</button>
</form>

关键修正点

  1. 表单结构稳定:不再覆盖formGroup,始终保持actualsVolumeData作为FormArray的容器。
  2. 数据与表单绑定:用createRowForm方法将每一行数据转换为带验证规则的FormGroup,添加到FormArray中,Mat Table的数据源直接绑定到rows.controls,确保UI和表单数据同步。
  3. 添加新行逻辑:onAdd方法直接操作FormArray,添加新的FormGroup,UI会自动更新。
  4. 验证与提交:提交按钮根据表单整体状态禁用,确保只有验证通过才能提交,同时显示字段级的验证错误提示。

内容的提问来源于stack exchange,提问作者AkRoy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:09:14