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
包含两个控件,FormGroup和 FormArray对于 key-value
和 key-value-list
分别。 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()
值并且做的非常非常少(所有工作都在 View 中完成):
@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>
ListView 类似:
<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
中的组件组件,但我碰壁了。假设我的应用程序 View 变为:
<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>
这似乎是一个合理的开始,但我不知道循环内部应该是什么。
最佳答案
实际上,您不需要将 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>
关于javascript - 嵌套的 Angular 响应式表单和组件重用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48601544/