TL; DR :将嵌套组件与嵌套reactive forms相结合,似乎有问题。每个嵌套组件都必须从[formGroupName],[formArrayName]和[formControlName]指令的组合构建整个表单层次结构。
明细:给定一个键值对建模为:
{
"key": string,
"value": string
}
单个键值对和列表键值对可以建模为:
{
"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
定义了一个模型以及使用FormGroup构建的相应FormBuilder:
@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
分别包含key-value
和key-value-list
两个控件FormGroup和FormArray。 FormArray是FormGroup的列表。
app.component.html
提供form
对应属于的控制组的顶级key-value
和名称:
<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
组件中重复使用key-value-list
组件,但我正在撞墙。假设我的应用程序视图变为:
<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>
这似乎是一个合理的开始,但我不知道循环内部应该是什么。
答案 0 :(得分:0)
实际上,您不需要将FormGroup实例和FormGroupName都传递给子组件,任何一个都可以。数组比单一控件有点棘手,但这样的东西应该有效:
<div [formGroup]="parentForm">
<div [formArrayName]="name">
<div *ngFor="let c of parentForm.get(name).controls; let i=index;">
<key-value [parentForm]="c"></key-value>
<!--<key-value [name]="i"></key-value> this should also work-->
</div>
</div>
</div>