创建和填充 Reactive FormArray Angular 10 [英] Create and Fill Reactive FormArray Angular 10
问题描述
更新:我想我越来越近了.这就是我现在所拥有的:
songEditForm = this.fb.group({标题: [null, [Validators.required, Validators.maxLength(128)]],projectId: [null, [Validators.required]],艺术家:[null, [Validators.required, Validators.maxLength(128)]],专辑:[null,[Validators.maxLength(128)]],分钟:[null, [Validators.min(0), Validators.max(99)]],秒:[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)]],评级:[null, [, Validators.min(0), Validators.max(5)]],ComfortLevel: [null, [, Validators.min(0), Validators.max(5)]],energyLevel: [null, [, Validators.min(0), Validators.max(11)]],注释:[null,[Validators.maxLength(512)]],流派:[空],isPublic: [null],isFavorite: [null],customSongProperties: this.fb.array([])});获取 customSongProperties() {将 this.songEditForm.get('customSongProperties') 作为 FormArray 返回;}<mat-card formArrayName="customSongProperties";*ngFor="let customSongProperty of customSongProperties.controls;让 i=index"><mat-form-field><mat-label>{{customSongProperty.value.label}}</mat-label><input matInput type="text";[formControlName]=i"名称=i"></mat-form-field></mat-card>
但我似乎无法将数组中的值绑定到表单数组中.
此行下方的原始帖子
我需要遍历一个对象/数组并创建零个或多个带标签的输入字段.我想将 Reactive 表单数组绑定到的对象具有标签和值属性(等等).我觉得我很接近,但我收到此错误消息:
错误错误:找不到带有路径的控件:'customSongProperties ->0 ->价值'
<mat-card *ngFor="let _ of customSongProperties.controls;索引为 i"><ng-container [formGroupName]=i"><input matInput formControlName="value.value";名称=索引"placeholder="value.label";最大长度=50"/></ng-容器></mat-card></ng-容器>
这是我尝试填充表单数组的方式:
this.data.customSongProperties.forEach(customSongProperty => {this.customSongProperties.push(new FormControl(customSongProperty));});
这是我绑定到并尝试从中构建表单字段的对象:
导出类 CustomSongProperty {身份证号码;用户 ID:号码;songPropertyDataTypeId:数字;SongPropertyDataTypeName: 字符串 |空值;标签:字符串 |空值;歌曲ID:编号;值:字符串 |空值;}
这对我来说似乎是正确的,但显然不是.我正在关注本教程:反应式表单数组教程但最后我的理解力有点崩溃.任何帮助表示赞赏.
谢谢
Jason,您可以创建 FromControls 的 FormArray 或 FormGroups 的 FormArray(如果表单数组的元素具有唯一属性或它们是对象).例如
//例如如果你的 json 对象是这样的,你需要一个 FormControls 的 FormArray标题:'我的标题'customSongProperties:['一','二','三']//例如.如果你的 json 对象是这样的,你需要一个 FormArrays 的 FormArrays标题:'我的标题'customSongProperties:[ {value:'one'},{value:'two'},{value:'three'}]
使用 FormControls 的 FormArray
<mat-card *ngFor="let customSongProperty of customSongProperties.controls;让我=索引"><mat-form-field><mat-label>{{customSongProperty.value.label}}</mat-label><!--您使用 [formControlName]=i";为了formArray 中的 uniq FormControl--><input matInput type="text";[formControlName]=i"></mat-form-field></mat-card>
但在你的情况下,你有一个 FormArray 的 FormArray,所以 .html 必须是
<!--看到您指出 [formGroupName]=i"--><mat-card *ngFor="let customSongProperty of customSongProperties.controls;让我=索引"[formGroupName]=i"><mat-form-field><mat-label>{{customSongProperty.value.label}}</mat-label><!--您使用 formControlName="nameOfProperty";请记住,您可以在表单组--><input matInput type="text";formControlName=值"></mat-form-field></mat-card>
关于如何创建 FormGroup,使用返回 FormGroup 并作为数据接收对象或 null 的函数总是很有趣.由于我们的 FormArray 是 FormGroup 的 FormArray 我们可以做
getCustomSongPropertiesFormGroup(data:any=null){//如果数据为空,我们通过缺陷创建一个对象数据=数据 ||{id:0,userId:0...}返回 this.fb.group({id: [data.id],用户 ID: [data.userId],...})}
并创建formGroup songEditForm
getSongFormGroup(data:any=null){//如果数据为空,我们通过缺陷创建一个对象数据=数据 ||{title:null,projectId:null...,customSongProperties:null}返回 this.fb.group({标题: [data.title, [Validators.required, Validators.maxLength(128)]],projectId: [data.projectId, [Validators.required]],...customSongProperties:data.customSongProperties?fb.array(data.customSongProperties.map(x=>this.getCustomSongPropertiesFormGroup(x)):[]})}
试着解释一些map",如果你在 data.customSongProperties 中有一个对象数组,你可以使用 map map(x=>this.getCustomSongPropertiesFormGroup 将这个对象数组转换成一个 formGroup 数组(x)
这是我们创建 formArray 的数组.
现在你可以使用,例如
//创建表单songEditFormthis.songEditForm=this.getSongFormGroup()//添加一个新的formArray元素this.customSongProperties.push(this.getCustomSongPropertiesFormGroup())
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.
ORIGINAL POST BELOW THIS LINE
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:
ERROR Error: Cannot find control with path: 'customSongProperties -> 0 -> value'
<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 Tutorial But my comprehension kind of fell apart at the end. Any help is appreciated.
Thank you
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'}]
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>
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>
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],
...
})
}
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)):
[]
})
}
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())
这篇关于创建和填充 Reactive FormArray Angular 10的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!