[英]Angular 2/4 Reactive Forms with arrays
我正在尝试创建我的第一个Angular 2应用程序。 和往常一样,我立即想创建的模型遇到麻烦。 我有一个用于在关节之间创建父子关系的模型。 例如:我想在我的购物篮中添加带有一些子对象的文章,如下所示:
IArticle[] = [
{
id: 1,
parentArticle: 1234596,
description: 'some description for parent'
children: [
{
id: 1,
childArticle: 123457,
childDescription: 'some description for first child'
},
{
id: 2,
childArticle: 123467,
childDescription: 'some description for second child'
},
.....
]
在打字稿中,我为文章定义了一个接口。 子对象具有其自己的接口,该接口略有不同。
因为这些子对象是固定的小集合,所以我想使用下拉列表添加这些子对象。 我希望这些对象在单击时显示为带有按钮的按钮(带有“您确定”问题的模式弹出窗口是可选的)。 所以我认为dropdownlist旁边的按钮应该将dropdownlist值添加到数组中。 当我将值添加到普通类型数组中时,此方法工作正常。 但是现在我想将此数组包装为“反应形式”。
有人可以帮助我如何在这些反应性表单中使用数组以及如何将它们包装在formcontrol对象中。 我看着FormArray的“控件”,但不确定这是我要搜索的内容。 它缝制了一个FormControls数组,而不是一个数据数组。 也许Reactive Forms是不正确的决定? 希望有人可以让我走上正确的道路。
我的html模板如下(从代码中剥离了引导代码)
<form autocomplete="off">
<input type="text" Placeholder="Article Number" />
<div >
<button *ngFor="let child of children">
<span class="glyphicon glyphicon-remove-circle text-danger"></span>
{{ child.childArticle }}
</button>
</div>
<div >
<select class="form-control inline">
<option value="">Select Service..</option>
<option *ngFor="let serviceOption of serviceOptions" [ngValue]="serviceOption.serviceNumber">
{{serviceOption.serviceDescription}}
</option>
</select>
<button (click)="onAddService()">
Add
</button>
</div>
<div>
<button type="submit">
Save
</button>
</div>
</form>
亲切的问候。
------打字稿代码:
export class NewServiceComponent implements OnInit {
newServiceForm: FormGroup;
serviceOptions: IServiceArticle[] = [
{ 'id': 1, 'serviceNumber': 123456, serviceDescription: 'description 1' },
{ 'id': 2, 'serviceNumber': 456789, serviceDescription: 'description 2' },
{ 'id': 3, 'serviceNumber': 123456, serviceDescription: 'description 3' },
];
selectedServiceOption: IServiceArticle;
newArticle: IService;
constructor(private _fb: FormBuilder) {
}
createForm() {
this.newServiceForm = this._fb.group({
services: this._fb.array([]),
articleNumber: this._fb.control(null, Validators.required),
})
}
ngOnInit() {
this.createForm();
}
onAddService() {
const arrayControl = <FormArray>this.newServiceForm.controls['services'];
let newgroup = this._fb.group({
serviceNumber: this.selectedServiceOption.serviceNumber,
serviceDescription: this.selectedServiceOption.serviceDescription,
})
arrayControl.push(newgroup);
}
}
创建反应式表单时,首先需要具有主表单组,并且在表单组中将具有formArray控件。 完成之后,您将向该formArray添加任何现有子项,并且这些子项中的每一个将是其自己的formGroup。
constructor(private fb: FormBuilder){
myTypeScriptChildrenObjects = functionToGetTheChildrenArray();
}
...
createForm(){
this.form = this.fb.group({
childrenArray: this.fb.array([])
})
const arrayControl = <FormArray>this.orderForm.controls['childrenArray'];
this.myTypeScriptChildrenObjects.forEach(item => {
let newGroup = this.fb.group({
prop1: [item.prop1],
prop2: [item.prop2],
prop3: [item.prop3]
})
arrayControl.push(newGroup);
})
}
在html中循环浏览这些内容时,您会执行以下操作:
<select formArrayName="childrenArray">
<option [formGroupName]="i" *ngFor="let line of form.controls['childrenArray'].controls; index as i" text="prop1" value="prop2">
尝试了以下代码,它似乎可以正常工作。
至于表单,您需要添加[formGroup]
,因此:
<form [formGroup]="newServiceForm">
并且由于它现在位于表单组中,因此如果没有表单控件,它将不接受[(ngModel)]
作为select
。 我们可以使用[ngModelOptions]="{standalone: true}"
来绕过它
然后我也会更改[ngValue]
以引用该对象: [ngValue]="serviceOption"
然后,就像您一样,将选择的值添加并推入表单数组。
在模板中,我们现在要迭代此表单数组。 总而言之,模板应如下所示:
<form [formGroup]="newServiceForm">
<div formArrayName="services">
<button *ngFor="let child of newServiceForm.controls.services.controls;
let i = index" [formGroupName]="i">
<span [innerHtml]="child.controls.serviceDescription.value"> </span>
</button>
</div>
<select [(ngModel)]="selectedServiceOption" [ngModelOptions]="{standalone: true}">
<option>Select Service..</option>
<option *ngFor="let serviceOption of serviceOptions" [ngValue]="serviceOption">
{{serviceOption.serviceDescription}}
</option>
</select>
<button (click)="onAddService()"> Add </button>
</form>
表单控件也可以设置为变量,这样您就可以避免那些长途旅行。
而且,正如评论中所讨论的那样,这并未考虑用户可以反复选择相同值的事实,但这与问题无关。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.