我的API响应就像
"groups": [{
"group_name": "GRP1"
"attributes": [{
"attribute_id": 1,
"attribute_name": "Frequency",
"value_reference": "tag"
}]
},
{
"group_name": "GRP2"
"attributes": [{
"attribute_id": 2,
"attribute_name": "Date",
"value_reference": "static",
"value_static_type": "date"
}]
}]
- 我如何在Angular 4中创建formConrol来显示像
这样的数据GroupName
List of Group's Attribute
GroupName
List of Group's Attribute
我的初始表单控件就像
this.editTemplateForm = this.fb.group({
groups: this.fb.group({
group_name: ['', Validators.required ],
attributes : this.fb.group({
value_reference : []
})
}),
});
我不明白如何动态添加控件
答案 0 :(得分:2)
如果您想要准确匹配您的API响应,那么此处的结构最终会相当复杂。由于到目前为止,每个attributes
属性只有一个属性对象,因此您可以直接使attributes
成为对象,而不是对象数组,这将简化以下代码。以下代码与您当前的API结构相匹配,可以在this working plunker播放。
要记住的一些事情:
FormGroup
需要是最外层的表单对象,也可用于保存不确定数量的FormControl
项FormArray
在控件数量不确定时非常有用,和调用这些控件无关紧要。 allGroups
是一个包含最大组的数组,attributes
是一个包含属性对象的数组,但这些属性对象本身就是组 - 因为我们希望能够根据API属性名称此结构也很有可能完全 你正在寻找的东西(例如,你可能并不希望所有这些值都是可编辑的<input>
字段),但它应该为您提供强有力的基础,以便了解如何根据更改的表单对象动态生成HTML。
import {Component} from '@angular/core';
import {FormGroup, FormControl, FormArray, FormBuilder} from '@angular/forms';
interface APIGroup {
'group_name': string;
'attributes': Array<GroupAttributes>
}
interface GroupAttributes {
'attribute_id': number;
'attribute_name': string;
'value_reference': string;
'value_static_type'?: string;
}
@Component({
selector: 'app-child',
template: `
<div>
<h3>I'm the Child component</h3>
</div>
<form [formGroup]="editTemplateForm">
<div formArrayName="allGroups">
<div *ngFor="let group of editTemplateForm.get('allGroups').controls; let i=index" [formGroupName]="i">
<input formControlName="groupName" />
<div formArrayName="attributes">
<div *ngFor="let attributeGroup of group.get('attributes').controls; let n=index" [formGroupName]="n">
<input *ngFor="let key of keysOfFormGroup(attributeGroup)" [formControlName]="key" />
</div>
</div>
<br/>
</div>
</div>
</form>
<pre style="background: #ddd">{{editTemplateForm.value | json}}</pre>
`,
})
export class ChildComponent {
constructor(
private fb: FormBuilder
) { }
sampleData: Array<APIGroup> = [
{
"group_name": "GRP1",
"attributes": [{
"attribute_id": 1,
"attribute_name": "Frequency",
"value_reference": "tag"
}]
},
{
"group_name": "GRP2",
"attributes": [{
"attribute_id": 2,
"attribute_name": "Date",
"value_reference": "static",
"value_static_type": "date"
}]
}
]
editTemplateForm: FormGroup;
ngOnInit() {
this.editTemplateForm = this.fb.group({
allGroups: this.fb.array([])
});
// would call on a subscription to actual api data
this.sampleData.forEach(group => {
(<FormArray>this.editTemplateForm.get('allGroups'))
.push(this.initGroup(group));
});
}
initGroup(apiGroup: APIGroup): FormGroup {
let formGroup = this.fb.group({
groupName: [apiGroup.group_name],
attributes: this.fb.array([])
});
apiGroup.attributes.forEach(attributeGroup => {
(<FormArray>formGroup.get('attributes'))
.push(this.initAttributeGroup(attributeGroup));
});
return formGroup;
}
initAttributeGroup(attributes: GroupAttributes): FormGroup {
let formGroup = this.fb.group({});
Object.keys(attributes).forEach(name => {
formGroup.addControl(name, new FormControl(attributes[name]));
});
return formGroup;
}
keysOfFormGroup(group: FormGroup): Array<string> {
return Object.keys(group.controls);
}
}