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

Angular FormArray最后一项FormControl无法获取输入值问题

Angular FormArray最后一项FormControl无法获取输入值问题解决

我在创建包含多个FormGroup的FormArray时遇到异常:FormArray最后一项中的FormControl无法获取输入值。以下是相关代码:

add-modules.ts 文件

import { ChangeDetectorRef, Component } from '@angular/core';
import { FormArray, FormControl, FormGroup, Validators } from '@angular/forms';

/** @title Basic drawer */
@Component({
  selector: 'app-module-new',
  templateUrl: 'app-module-new.html',
  styleUrls: ['app-module-new.css'],
})
export class AppModuleNewComponent {
  moduleForm: FormGroup;

  constructor(private changeDetectorRef: ChangeDetectorRef) {
    this.moduleForm = new FormGroup({
      name: new FormControl('', [Validators.required]),
      description: new FormControl('', [Validators.required]),
      lessons: new FormArray([
        new FormGroup({
          type: new FormControl('lesson'),
          name: new FormControl('', [Validators.required]),
          description: new FormControl(''),
        }),
      ]),
    });
  }
  ngAfterViewChecked(): void {
    this.changeDetectorRef.detectChanges();
  }
  private newLesson() {
    return new FormGroup({
      type: new FormControl('lesson'),
      name: new FormControl('', [Validators.required]),
      description: new FormControl(''),
    });
  }

  addLesson() {
    (this.moduleForm.get('lessons') as FormArray).controls.push(
      this.newLesson()
    );
  }
  getLessonsControl() {
    return (this.moduleForm.get('lessons') as FormArray).controls;
  }

  submitForm() {
    console.log(this.moduleForm);
  }
}

add-module.html 文件

<div class="container text-grey" style="width: 80%; margin: 0 auto">
  <h1>HELLo</h1>

  <form [formGroup]="moduleForm" (submit)="submitForm()">
    <div>
      <label>Input</label>
      <input type="text" formControlName="name" />
    </div>

    <div>
      <label>Desc</label>
      <input type="text" formControlName="description" />
    </div>

    <div
      formArrayName="lessons"
      *ngFor="let line of getLessonsControl();let i=index "
    >
      Lesson {{i+1}}
      <div [formGroupName]="i">
        <div>
          <label>Name</label>
          <input type="text" formControlName="name" />
        </div>
        <div>
          <label>desc</label>
          <input type="text" formControlName="description" />
        </div>
      </div>
    </div>
    <button type="button" (click)="addLesson()">Add Lesson</button>
    <button type="submit">SUBMIT</button>
  </form>
</div>

问题原因

问题出在addLesson方法中,直接操作FormArray的controls数组来添加新控件,这种方式绕过了Angular表单的内部变更检测机制,导致最后一项的视图与FormControl实例无法正确绑定,输入值无法同步到模型中。

解决方案

修改代码,使用FormArray原生的push方法添加控件,同时优化模板中获取FormArray控件的方式:

修改后的 add-modules.ts 关键代码

// 替换原addLesson方法
addLesson() {
  (this.moduleForm.get('lessons') as FormArray).push(this.newLesson());
}

// 替换原getLessonsControl方法,改用属性访问器
get lessonsFormArray(): FormArray {
  return this.moduleForm.get('lessons') as FormArray;
}

修改后的 add-module.html 关键代码

<!-- 替换原FormArray循环部分 -->
<div
  formArrayName="lessons"
  *ngFor="let line of lessonsFormArray.controls; let i=index "
>

说明

  • 使用FormArray的push方法,Angular会自动处理表单的变更检测,确保视图与模型同步
  • 将方法改为属性访问器,避免模板中频繁调用方法触发不必要的变更检测,提升性能同时避免潜在的绑定问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 09:35:34