[英]How can I use FormArray with FormGroups with Angular reactive forms?
I am trying to mimic my model in my reactive form.我试图以我的反应形式模仿我的 model。 I've set up a few FormGroups to "nest" things that make sense according to my model. I'm having trouble setting up my component to read the values--which suggests that I likely don't have my template set up correctly either.
我已经设置了一些 FormGroups 来“嵌套”根据我的 model 有意义的东西。我在设置我的组件以读取值时遇到了问题——这表明我可能没有正确设置我的模板任何一个。
Depending if I am editing an existing location or creating a new one,取决于我是在编辑现有位置还是创建新位置,
@Input() location: ILocation;
could be undefined
.可能是
undefined
的。 Currently I am only focused on working with an existing location, so I know location
has a value.目前我只专注于使用现有位置,所以我知道
location
是有价值的。
// location.model.ts
name: string;
...
messaging: [
{
email: {
fromName: string;
fromAddress: string;
};
}
];
...
createdAt?: string;
updatedAt?: string;
deletedAt?: string;
In my template I am using ngClass
to give the user validation feedback:在我的模板中,我使用
ngClass
为用户提供验证反馈:
// location.commponent.html
<div formGroupName="messaging">
<div formGroupName="email">
...
<div [ngClass]="form.get(['messaging', 'email', 'fromName'])!.errors && (form.get(['messaging', 'email', 'fromName'])!.dirty || form.get(['messaging', 'email', 'fromName'])!.touched) ? 'red' : 'green'">
<input name="fromName"/>
</div>
<!-- fromAddress -->
</div>
</div>
In my component, I am passing the model in with input binding, then setting up my form goup(s) and form fields like this:在我的组件中,我通过输入绑定传递 model,然后设置我的表单组和表单字段,如下所示:
// location.component.ts
@Input() location: ILocation;
form: FormGroup;
...
ngOnInit(): void {
this.form = new FormGroup({name: new FormControl(this.location.name, [Validators.required]),
messaging: new FormGroup({
email: new FormGroup({
fromName: new FormControl(this.location.messaging[0].email.fromName, [Validators.required]),
fromAddress: new FormControl(this.location.messaging[0].email.fromAddress, [Validators.required]),
}),
}),
}
The error I am seeing is:我看到的错误是:
Cannot read properties of undefined (reading 'email')
无法读取未定义的属性(读取“电子邮件”)
If I log out what is in the component:如果我注销组件中的内容:
console.log('messaging: ', this.location.messaging);
// email: {fromName: 'No Reply <noreply@example.com>', fromAddress: 'noreply@example.com'}
I've tried various methods of messaging['email']
or messaging.email
messaging[0]
but I can't seem to find the correct path.我尝试了各种
messaging['email']
或messaging.email
messaging[0]
方法,但我似乎找不到正确的路径。
I am also not sure if I am using the get()
method correctly in my template.我也不确定我是否在我的模板中正确使用了
get()
方法。
How can I set up my form to read/present the data correctly?如何设置我的表单以正确读取/显示数据?
Update:更新:
Not surprisingly, a big problem I was having was sending the wrong shape of data back.毫不奇怪,我遇到的一个大问题是发回错误形状的数据。
In the end, this is the JSON I am trying to create:最后,这是我要创建的 JSON:
[{"email":{"fromName":"No Reply <noreply@example.com>","fromAddress":"noreply@example.com"}}]
It looks like I need to use FormArray to send the proper shape:看起来我需要使用FormArray来发送正确的形状:
messaging: new FormArray([
new FormGroup({
email: new FormGroup({
fromName: new FormControl(this.location.messaging[0].email.fromName, [Validators.required]),
fromAddress: new FormControl(this.location.messaging[0].email.fromAddress, [Validators.required]),
}),
}),
]),
This is causing some trouble in my template as I'm currently doing this: form.get('messaging[0].email.fromAddress')
这在我的模板中造成了一些麻烦,因为我目前正在这样做:
form.get('messaging[0].email.fromAddress')
Resulting in:导致:
Error: Cannot find control with path: 'messaging -> email'
错误:找不到路径为“消息传递 -> 电子邮件”的控件
I think I need to somehow loop through the FormArray
.我想我需要以某种方式循环遍历
FormArray
。 This really isn't a dynamic array though.不过,这确实不是动态数组。 I'll always have
email
and only fromName
and fromAddress
.我将始终拥有
email
并且只有fromName
和fromAddress
。
Yes, you need the FormArray
as the messaging
is an array.是的,您需要
FormArray
,因为messaging
是一个数组。
You need to iterate every element in FormArray
via *ngFor
and provide the index ( i
):您需要通过
*ngFor
迭代FormArray
中的每个元素并提供索引( i
):
form.get(['messaging', i, 'email', 'fromName'])
The complete flow of your template form from parent FormGroup to fromName
FormControl
would be:从父 FormGroup 到
fromName
FormControl
的模板表单的完整流程是:
form (
FormGroup
) --> messaging (FormArray
) --> i (FormGroup
) --> email (FormGroup
) --> fromName (FormControl
)表单 (
FormGroup
) --> 消息 (FormArray
) --> i (FormGroup
) --> email(FormGroup
) --> fromName(FormControl
)
The HTML template should be: HTML 模板应该是:
<div [formGroup]="form">
<div
formArrayName="messaging"
*ngFor="let control of messaging.controls; let i = index"
>
<ng-container [formGroupName]="i">
<div formGroupName="email">
...
<div
[ngClass]="
form.get(['messaging', i, 'email', 'fromName'])!.errors &&
(form.get(['messaging', i, 'email', 'fromName'])!.dirty ||
form.get(['messaging', i, 'email', 'fromName'])!.touched)
? 'red'
: 'green'
"
>
<input formControlName="fromName" />
</div>
<div>
<!-- fromAddress -->
<input formControlName="fromAddress" />
</div>
</div>
</ng-container>
</div>
</div>
get messaging(): FormArray {
return this.form.get('messaging') as FormArray;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.