动态嵌套表单控件Angular 2
Posted
技术标签:
【中文标题】动态嵌套表单控件Angular 2【英文标题】:Dynamic nested form controls Angular 2 【发布时间】:2018-02-21 23:31:44 【问题描述】:我的 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 : []
)
),
);
我不明白如何动态添加控件
【问题讨论】:
【参考方案1】:如果您想完全匹配您的 API 响应,这里的结构最终会相当复杂。由于到目前为止,每个attributes
属性只有一个属性对象,因此您可以直接将attributes
设为对象,而不是对象数组,这将简化以下代码。下面的代码符合你当前的 API 结构,可以在this working plunker 玩。
注意事项:
FormGroup
需要是最外层的表单对象,也可以用来容纳不定数量的FormControl
项目
另一方面,FormArray
在控件的数量不确定时很有用,并且这些控件的名称并不重要。
这就是为什么,下面,allGroups
是一个包含最大组的数组,attributes
是一个包含您的属性对象的数组,但这些属性对象本身就是组 - 因为我们希望能够命名控件基于其 API 属性名称
这个结构也很有可能不是完全您正在寻找的(例如,也许您不希望所有这些值都是可编辑的<input>
字段),但它应该为您在 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);
【讨论】:
感谢@JackKoppa 的回复。你的回答肯定给了我一些想法,让我继续我的 API 响应。我还发现了另一个有用的 Plunker 链接 - plnkr.co/edit/hpuPdh?p=preview。再次感谢 对不起,上面的链接是你的。我发现的是 - plnkr.co/edit/3k23R3z2KHlAXW5OLKRA?p=preview 不错,那个笨拙的看起来也很适用。如果此答案足够,请随时将其标记为已接受,如果您有任何其他问题,请告诉我 嘿@JackKoppa 你知道我如何将新的表单组控件添加到“属性”吗?单击按钮时,我需要添加组和新的属性行。我设法添加新组,但不知道如何添加属性 应该像formArray.push()
一样简单,传入新的FormGroup
。让我尝试用那种按钮更新 plunk以上是关于动态嵌套表单控件Angular 2的主要内容,如果未能解决你的问题,请参考以下文章