如何从子表单自身移除嵌套子表单?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
相关产品推荐
相关产品推荐

