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

如何从子表单自身移除嵌套子表单?Angular表单实现

解决方案

核心思路是通过子组件触发事件通知父组件执行删除操作,保持子组件的通用性,不依赖特定父组件的实现。

步骤1:子组件添加事件发射器并实现delete方法

在profile-form.component.ts中,定义@Output事件用于向父组件发送删除请求,同时在delete()方法中触发该事件:

import { Component, Input, Output, EventEmitter } from '@angular/core';
import { FormGroup, ControlValueAccessor, NG_VALUE_ACCESSOR, FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'app-profile-form',
  templateUrl: './profile-form.component.html',
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: ProfileFormComponent,
      multi: true
    }
  ]
})
export class ProfileFormComponent implements ControlValueAccessor {
  @Input() formIndex!: number;
  form: FormGroup;

  // 定义删除请求事件,传递当前表单索引
  @Output() deleteRequest = new EventEmitter<number>();

  constructor(private fb: FormBuilder) {
    this.form = this.fb.group({
      firstName: ['', Validators.required],
      email: ['', Validators.required]
    });
  }

  // 实现ControlValueAccessor的必要方法(writeValue、registerOnChange等,此处省略已实现的代码)
  // ...

  delete() {
    // 触发删除事件,通知父组件执行删除
    this.deleteRequest.emit(this.formIndex);
  }

  // 方便模板访问表单控件
  get firstNameControl() {
    return this.form.get('firstName')!;
  }

  get emailControl() {
    return this.form.get('email')!;
  }
}

步骤2:父组件绑定事件并实现删除逻辑

在父组件模板中,给app-profile-form绑定deleteRequest事件,关联父组件的删除方法:

<ng-container formArrayName="formList">
  <div *ngFor="let fg of formList.controls; let infoIndex = index">
    <app-profile-form
      [formControlName]="infoIndex"
      [formIndex]="infoIndex"
      (deleteRequest)="deleteForm(infoIndex)"
    ></app-profile-form>
  </div>
</ng-container>

在父组件类中实现deleteForm方法,从FormArray中移除对应索引的控件:

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent {
  signupForm: FormGroup;

  constructor(private formBuilder: FormBuilder) {
    this.signupForm = this.formBuilder.group({
      formList: this.formBuilder.array([this.formListGroupDef()]),
    });
  }

  // 修正原代码错误:返回FormGroup而非FormControl,匹配子表单的结构
  formListGroupDef() {
    return this.formBuilder.group({
      firstName: '',
      email: '',
    }, Validators.required);
  }

  addForm() {
    this.formList.push(this.formListGroupDef());
  }

  // 实现删除逻辑
  deleteForm(index: number) {
    this.formList.removeAt(index);
  }

  get formList() {
    return this.signupForm.get('formList') as FormArray;
  }
}

关键说明

  • 子组件通过@Output解耦与父组件的依赖,确保它能在不同父表单中复用。
  • 修正了父组件formListGroupDef的错误:原代码返回formBuilder.control,但此处需要包含两个子控件的FormGroup,否则子表单的formGroup绑定会失效。
  • 父组件通过removeAt(index)方法正确从FormArray中移除对应项,保证表单数组的同步更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 13:47:04