问题描述
更新:我想我越来越近了.这就是我现在拥有的:
Update: I think I'm getting closer. This is what I have now:
songEditForm = this.fb.group({
title: [null, [Validators.required, Validators.maxLength(128)]],
projectId: [null, [Validators.required]],
artist: [null, [Validators.required, Validators.maxLength(128)]],
album: [null, [Validators.maxLength(128)]],
minutes: [null, [Validators.min(0), Validators.max(99)]],
seconds: [null, [, Validators.min(0), Validators.max(59)]],
songParts: [null, [Validators.maxLength(4000)]],
timeSignature: [null, [Validators.maxLength(10)]],
songKey: [null, [Validators.maxLength(10)]],
bpm: [null, [, Validators.min(0), Validators.max(320)]],
rating: [null, [, Validators.min(0), Validators.max(5)]],
comfortLevel: [null, [, Validators.min(0), Validators.max(5)]],
energyLevel: [null, [, Validators.min(0), Validators.max(11)]],
notes: [null, [Validators.maxLength(512)]],
genre: [null],
isPublic: [null],
isFavorite: [null],
customSongProperties: this.fb.array([])
});
get customSongProperties() {
return this.songEditForm.get('customSongProperties') as FormArray;
}
<mat-card formArrayName="customSongProperties" *ngFor="let customSongProperty of customSongProperties.controls; let i=index">
<mat-form-field>
<mat-label>{{customSongProperty.value.label}}</mat-label>
<input matInput type="text" [formControlName]="i" name="i">
</mat-form-field>
</mat-card>
但是我似乎无法将数组中的值绑定到表单数组中.
But I can't seem to bind the values from my array into the form array.
我需要遍历对象/数组,并创建带有标签的零个或多个输入字段.我想将Reactive表单数组绑定到的对象具有label和value属性(以及其他属性).我觉得我已经接近了,但是却收到了此错误消息:
I need to loop through an object/array and create zero or more input fields with labels. The object I want to bind the Reactive form array to has label and value properties (amongst others). I feel like I am close but I am getting this error message:
错误错误:找不到路径为'customSongProperties->的控件.0->值"
<ng-container formArrayName="customSongProperties">
<mat-card *ngFor="let _ of customSongProperties.controls; index as i">
<ng-container [formGroupName]="i">
<input matInput formControlName="value.value" name="index" placeholder="value.label" maxlength="50" />
</ng-container>
</mat-card>
</ng-container>
这是我尝试填写表单数组的方式:
This is how I am trying to fill the form array:
this.data.customSongProperties.forEach(customSongProperty => {
this.customSongProperties.push(new FormControl(customSongProperty));
});
这是我要绑定的对象,并试图从以下对象构建表单字段:
This is the object I am binding to and trying to build form fields from:
export class CustomSongProperty {
id: number;
userId: number;
songPropertyDataTypeId: number;
songPropertyDataTypeName: string | null;
label: string | null;
songId: number;
value: string | null;
}
这对我来说似乎是正确的,但显然并非如此.我正在关注本教程:反应形式数组教程但是我的理解力最终却崩溃了.感谢您的帮助.
This seems right to me, but clearly is not.I was following this tutorial:Reactive Form Array TutorialBut my comprehension kind of fell apart at the end.Any help is appreciated.
谢谢
推荐答案
Jason,您可以创建FromControls的FormArray或FormGroups的FormArray(如果表单数组的元素具有唯一属性或它们是对象).例如
Jason, you can create a FormArray of FromControls or a FormArray of FormGroups (if the elements of the form array has an unique property or they are objects). e.g.
//e.g. you need a FormArray of FormControls if your json object is like
title:'my title'
customSongProperties:[ 'one','two','three']
//e.g. you need a FormArray of FormGroups if your json object is like
title:'my title'
customSongProperties:[ {value:'one'},{value:'two'},{value:'three'}]
使用您使用的FormControl的FormArray
With a FormArray of FormControls you use
<div formArraName="customSongProperties">
<mat-card *ngFor="let customSongProperty of customSongProperties.controls;
let i=index" >
<mat-form-field>
<mat-label>{{customSongProperty.value.label}}</mat-label>
<!--you use [formControlName]="i" for the
uniq FormControl in the formArray-->
<input matInput type="text" [formControlName]="i" >
</mat-form-field>
</mat-card>
</div>
但是在您的情况下,您有一个FormGroups的FormArray,因此.html必须是
But in your case you has a FormArray of FormGroups, so the .html must be
<div formArraName="customSongProperties">
<!--see that you indicate [formGroupName]="i"-->
<mat-card *ngFor="let customSongProperty of customSongProperties.controls;
let i=index" [formGroupName]="i">
<mat-form-field>
<mat-label>{{customSongProperty.value.label}}</mat-label>
<!--you use formControlName="nameOfProperty"
remember that you can has severals FormsControls in the
FormGroup
-->
<input matInput type="text" formControlName="value" >
</mat-form-field>
</mat-card>
</div>
关于如何创建FormGroup,总是很有趣的是使用一个返回FormGroup并将其作为数据获取为对象或null的函数.因为我们的FormArray是FormGroup的FormArray,所以我们可以做
About how create a FormGroup, always is interesting use a function that return a FormGroup and recived as data an object or null. As our FormArray is a FormArray of FormGroup we can do
getCustomSongPropertiesFormGroup(data:any=null)
{
//if data is null we create an object by defect
data=data || {id:0,userId:0...}
return this.fb.group({
id: [data.id],
userId: [data.userId],
...
})
}
并创建formGroup songEditForm
And to create the formGroup songEditForm
getSongFormGroup(data:any=null)
{
//if data is null we create an object by defect
data=data || {title:null,projectId:null...,customSongProperties:null}
return this.fb.group({
title: [data.title, [Validators.required, Validators.maxLength(128)]],
projectId: [data.projectId, [Validators.required]],
...
customSongProperties:data.customSongProperties?
fb.array(data.customSongProperties
.map(x=>this.getCustomSongPropertiesFormGroup(x)):
[]
})
}
请尝试解释一些地图",如果您在data.customSongProperties中包含一个对象数组,则可以使用地图 map(x => this.getCustomSongPropertiesFormGroup(x)
这是我们创建formArray的数组.
Try explain a few the "map", if you has in data.customSongProperties an array of objects, you transform this array of object in an array of formGroup using map map(x=>this.getCustomSongPropertiesFormGroup(x)
this is the array with we create the formArray.
现在您可以使用了,例如
Now you can use,e.g.
//to create the form songEditForm
this.songEditForm=this.getSongFormGroup()
//to add a new element of the formArray
this.customSongProperties.push(this.getCustomSongPropertiesFormGroup())
这篇关于创建并填充反应性FormArray Angular 10的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!