Angular 动态嵌套窗体控件角度2
我的API响应如下Angular 动态嵌套窗体控件角度2,angular,angular2-forms,angular2-formbuilder,angular-forms,Angular,Angular2 Forms,Angular2 Formbuilder,Angular Forms,我的API响应如下 "groups": [{ "group_name": "GRP1" "attributes": [{ "attribute_id": 1, "attribute_name": "Frequency", "value_reference": "tag"
"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 : []
})
}),
});
我不明白如何动态添加控件,如果您想精确匹配API响应,这里的结构会变得相当复杂。由于到目前为止,每个
attributes
属性只有一个属性对象,因此可以直接将attributes
作为对象,而不是对象数组,这将简化以下代码。下面的代码与您当前的API结构相匹配,可以在中使用
要记住的一些事情:
需要是最外层的表单对象,也可以用来保存数量不确定的FormGroup
项FormControl
- 另一方面,当控件的数量不确定时,
很有用,并且这些控件的名称无关紧要李>FormArray
- 这就是为什么在下面,
是一个包含最大组的数组,allGroups
是一个包含属性对象的数组,但这些属性对象本身就是组,因为我们希望能够根据它们的API属性名来命名控件attributes
- 这就是为什么在下面,
字段),但是它应该给你一个在plunker上使用的强大基础,并理解你如何根据改变的表单对象动态生成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);
}
}
从'@angular/core'导入{Component};
从'@angular/forms'导入{FormGroup,FormControl,FormArray,FormBuilder};
接口APIGroup{
“组名称”:字符串;
“属性”:数组
}
接口组属性{
'attribute_id':编号;
“属性名称”:字符串;
“值\引用”:字符串;
'值\静态\类型'?:字符串;
}
@组成部分({
选择器:“应用程序子项”,
模板:`
我是孩子
{{editTemplateForm.value | json}}
`,
})
导出类子组件{
建造师(
私人fb:FormBuilder
) { }
sampleData:数组=[
{
“组名称”:“GRP1”,
“属性”:[{
“属性_id”:1,
“属性名称”:“频率”,
“值\参考”:“标记”
}]
},
{
“集团名称”:“GRP2”,
“属性”:[{
“属性_id”:2,
“属性名称”:“日期”,
“价值参考”:“静态”,
“值\静态\类型”:“日期”
}]
}
]
editTemplateForm:FormGroup;
恩戈尼尼特(){
this.editTemplateForm=this.fb.group({
所有组:this.fb.array([])
});
//将调用对实际api数据的订阅
this.sampleData.forEach(组=>{
(this.editTemplateForm.get('allGroups'))
.push(this.initGroup(group));
});
}
initGroup(apiGroup:apiGroup):FormGroup{
让formGroup=this.fb.group({
groupName:[apiGroup.group\u name],
属性:this.fb.array([])
});
apiGroup.attributes.forEach(attributeGroup=>{
(formGroup.get('attributes'))
.push(this.initAttributeGroup(attributeGroup));
});
返回表单组;
}
initAttributeGroup(属性:GroupAttributes):FormGroup{
设formGroup=this.fb.group({});
Object.keys(attributes).forEach(name=>{
addControl(名称,新FormControl(属性[名称]);
});
返回表单组;
}
KeyOfforMgroup(组:FormGroup):数组{
返回对象键(组控件);
}
}
谢谢@JackKoppa的回复。你的回答肯定给了我一些想法来继续我的API响应。我还发现了另一个有用的Plunker链接-。再次感谢,以上链接是您的。我发现很好,plunk看起来也很适用。如果这个答案足够,请随时将其标记为已接受,如果您有任何其他问题,请告诉我。Y@JackKoppa您知道我如何将新表单组控件添加到“属性”中吗?单击按钮时,我需要添加组和新属性行。我设法添加了新的组,但不知道如何添加属性应该像formArray.push()
一样简单,传入新的FormGroup
。让我尝试用这种按钮更新plunk