TL;DR :将嵌套组件与嵌套reactive forms组合似乎有问题 . 每个嵌套组件都必须从[formGroupName],[formArrayName]和[formControlName]指令的组合构建整个表单层次结构 .
Detail :给定键值对建模为:
{
"key": string,
"value": string
}
single 键值对和 list 键值对可以建模为:
{
"one": {
"key": "Key A",
"value": "Value A"
},
"many": [
{
"key": "Key A",
"value": "Value A"
},
{
"key": "Key B",
"value": "Value B"
},
{
"key": "Key C",
"value": "Value C"
}
]
}
它看起来像Angular Reactive Forms和嵌套的 @Component
的组合应该使这个微不足道 .
我创建了以下组件层次结构和项目结构:
│ app.component.html
│ app.component.ts
│ app.module.ts
│
├───key-value
│ key-value.component.html
│ key-value.component.ts
│
└───key-value-list
key-value-list.component.html
key-value-list.component.ts
应用程序组件 app.component.ts
定义了一个模型,并使用FormBuilder构建了相应的FormGroup:
@Component({
selector: 'my-app',
templateUrl: './app.component.html'
})
export class AppComponent {
public form: FormGroup;
public model = {
one: {
key: 'Key A',
value: 'Value A'
},
many: [
{
key: 'Key A',
value: 'Value A'
},
{
key: 'Key B',
value: 'Value B'
},
{
key: 'Key C',
value: 'Value C'
}
]
};
constructor(private readonly fb: FormBuilder) { }
public ngOnInit(): void {
const items: FormGroup[] = this.model.many.map(pair => {
return this.fb.group(pair);
});
this.form = this.fb.group({
one: this.fb.group(this.model.one),
many: this.fb.array(items)
});
}
}
一开始介绍的模型应该很容易识别 . form
包含两个控件,FormGroup和FormArray分别用于 key-value
和 key-value-list
. FormArray是FormGroup的列表 .
app.component.html
提供 key-value
对应属于的控制组的顶级 form
和 name :
<key-value [parentForm]="form" name="one"></key-value>
<pre>{{ form.value | json }}</pre>
传输表单值以进行调试和格式化( <pre>
) . key-value.component.ts
接受两个 Input()
值并且非常非常少(所有工作都在视图中完成):
@Component({
selector: 'key-value',
templateUrl: './key-value.component.html'
})
export class KeyValueComponent {
@Input() public parentForm: FormGroup;
@Input() public name: string;
}
工作在 key-value.component.html
中完成,使用两个 Input()
值构建控件层次结构:
<div [formGroup]="parentForm">
<div [formGroupName]="name">
<mat-form-field>
<input matInput formControlName="key" placeholder="Key">
</mat-form-field>
<mat-form-field>
<input matInput formControlName="value" placeholder="Value">
</mat-form-field>
</div>
</div>
列表视图类似:
<div [formGroup]="parentForm">
<div [formArrayName]="name">
<div *ngFor="let c of parentForm.get(name).controls; let i=index;" [formGroupName]="i">
<mat-form-field>
<input matInput formControlName="key" placeholder="Key">
</mat-form-field>
<mat-form-field>
<input matInput formControlName="value" placeholder="Value">
</mat-form-field>
</div>
</div>
</div>
这有效 . 但我想重新使用 key-value-list
组件中的 key-value
组件,但我正在撞墙 . 假设我的应用程序视图变为:
<div [formGroup]="parentForm">
<div [formArrayName]="name">
<div *ngFor="let c of parentForm.get(name).controls; let i=index;" [formGroupName]="i">
<key-value [parentForm]="??????" name="??????"></key-value>
</div>
</div>
</div>
这似乎是一个合理的开始,但我不知道循环内部应该是什么 .
1 回答
实际上,您不需要将FormGroup实例和FormGroupName都传递给子组件,任何一个都可以 . 数组比单一控件有点棘手,但这样的东西应该有效: