作为另一种解决方案,我建议使用表单数组,在处理循环时,请查看此示例以供参考。
import 'zone.js';
import {
Component,
inject,
OnInit,
signal,
WritableSignal,
} from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import {
FormBuilder,
FormsModule,
ReactiveFormsModule,
FormControl,
FormArray,
FormGroup,
} from '@angular/forms';
@Component({
selector: 'app-root',
standalone: true,
imports: [ReactiveFormsModule, FormsModule],
template: `
<form [formGroup] = 'employeeForm'>
<input formControlName='orgName'>
<div formArrayName="dynamicContent">
@for(group of formArrayControls();track group; let i = $index){
<div [formGroupName]="i">
@for(controlObj of formObj;track controlObj){
<input [formControlName]="controlObj.formControlName"
[type]="controlObj.type"/>
}
</div>
}
</div>
<button (click) ='addControl()'>Add</button>
</form>
`,
})
export class App implements OnInit {
fb = inject(FormBuilder);
showEmpInfo: WritableSignal<any[]> = signal([]);
employeeForm = this.fb.group({
orgName: [''],
dynamicContent: this.fb.array([]),
});
formObj = [
{
type: 'text',
formControlName: 'employee',
},
{
type: 'text',
formControlName: 'empId',
},
];
ngOnInit() {
this.employeeForm.valueChanges.subscribe((val) => console.log(val));
}
formArrayControls() {
return (this.employeeForm!.get('dynamicContent') as FormArray)!
.controls as FormGroup[];
}
addControl() {
const dynamicForm = this.employeeForm.controls[
'dynamicContent'
] as FormArray;
const formGroup = this.fb.group({});
this.formObj.forEach((elem) => {
formGroup.addControl(elem.formControlName, new FormControl('', []));
});
dynamicForm.push(formGroup);
this.showEmpInfo.update((prev) => {
prev.push(this.formObj);
return prev;
});
}
}
bootstrapApplication(App);
您添加的控件不正确,必须使用以下方法添加控件
addControl
。我们引用动态内容并将其分配给
dynamicForm
,然后当我们循环遍历数组时,我们使用add控件直接添加控件。
addControl() {
const dynamicForm = this.employeeForm.controls['dynamicContent'];
this.formObj.forEach((elem) => {
dynamicForm.addControl(elem.formControlName, new FormControl('', []));
});
this.showEmpInfo.set(this.formObj);
}
完整代码:
import 'zone.js';
import {
Component,
inject,
OnInit,
signal,
WritableSignal,
} from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import {
FormBuilder,
FormsModule,
ReactiveFormsModule,
FormControl,
} from '@angular/forms';
@Component({
selector: 'app-root',
standalone: true,
imports: [ReactiveFormsModule, FormsModule],
template: `
<form [formGroup] = 'employeeForm'>
<input formControlName='orgName'>
@if(showEmpInfo().length > 0){
<div formGroupName="dynamicContent">
@for(emp of showEmpInfo();track emp){
<input type = 'text'
[formControlName] = "emp.formControlName">
}
</div>
}
<button (click) ='addControl()'>Add</button>
</form>
`,
})
export class App implements OnInit {
fb = inject(FormBuilder);
showEmpInfo: WritableSignal<any[]> = signal([]);
employeeForm = this.fb.group({
orgName: [''],
dynamicContent: this.fb.group({}),
});
formObj = [
{
type: 'text',
formControlName: 'employee',
},
{
type: 'text',
formControlName: 'empId',
},
];
ngOnInit() {
this.employeeForm.valueChanges.subscribe((val) => console.log(val));
}
addControl() {
const dynamicForm = this.employeeForm.controls['dynamicContent'];
this.formObj.forEach((elem) => {
dynamicForm.addControl(elem.formControlName, new FormControl('', []));
});
this.showEmpInfo.set(this.formObj);
}
}
bootstrapApplication(App);