更新时间:2023-10-10 21:35:22
请勿使用 [(ngModel)]
!反应形式要好得多.它们使手动 ngModel
绑定变得过时,并且具有一些非常漂亮的内置功能,在本答案中,我仅介绍其中的几个.
Don't use [(ngModel)]
! Reactive forms are much nicer. They make manual ngModel
bindings obsolete, and they have some pretty sweet built-in features that only a couple of which I'm going to cover in this answer.
如果要绑定到诸如文本输入之类的表单控件,请使用以下模板语法:
If you're binding to a form control such as a text input, use this template syntax:
<ng-container [formGroup]="this.myFormGroup">
<input type="text" formControlName="field1">
<input type="text" formControlName="field2">
<ng-container formGroupName="subgroupName">
<input type="text" formControlName="subfield2">
</ng-container>
<input type="text" formControlName="myRequiredField">
</ng-container>
(( field1
, field2
, subgroupName
, subfield2
和 myRequiredField
是与表单各部分相对应的任意控件和控件组名称,创建 FormGroup
对象时,请参见下文.)
(field1
, field2
, subgroupName
, subfield2
, and myRequiredField
are all arbitrary control and control group names that correspond to parts of your form, see below when creating the FormGroup
object.)
与 FormGroup
的模型的只读数据绑定在模板中的访问有所不同:
Read-only data bindings to the model of the FormGroup
are accessed a little differently in your template:
{{ this.myFormGroup.get('field1').value }}
{{ this.myFormGroup.get('subgroupName.subfield2').value }}
<!-- Hint: use an array if you have field names that contain "." -->
{{ this.myFormGroup.get(['subgroupName', 'subfield2']).value }}
FormGroup
在您的组件类的 constructor()
中(应该在模板呈现之前),使用以下语法来构建一个与该表单对话的表单组:
FormGroup
In your component class, in constructor()
(this should be before the template renders), use the following syntax to build a form group to talk to this form:
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
...
public readonly myFormGroup: FormGroup;
...
constructor(private readonly formBuilder: FormBuilder) {
this.myFormGroup = this.formBuilder.group({
field1: [],
field2: [],
subgroupName: this.formBuilder.group({
subfield2: [],
}),
myRequiredField: ['', Validators.required],
});
this.retrieveData();
}
如果您的组件需要在加载时从服务中检索数据,则必须确保它在构建表单后开始传输,然后使用 patchValue()
从您的服务中放入数据对象放入 FormGroup
:
If your component needs to retrieve data from a service as it loads, you must make sure it starts the transfer after the form has been built, then use patchValue()
to put the data from your object into the FormGroup
:
private retrieveData(): void {
this.dataService.getData()
.subscribe((res: SomeDataStructure) => {
// Assuming res has a structure like:
// res = {
// field1: "some-string",
// field2: "other-string",
// subgroupName: {
// subfield2: "another-string"
// },
// }
// Values in res that don't line up to the form structure
// are discarded. You can also pass in your own object you
// construct ad-hoc.
this.myFormGroup.patchValue(res);
});
}
现在,假设您的用户单击了提交,现在您需要从表单中获取数据,然后通过服务将其 POST
返回到您的API.只需使用 getRawValue
:
Now, say your user clicks submit and now you need to get the data back out of your form and POST
it back to your API thru a service. Just use getRawValue
:
public onClickSubmit(): void {
if (this.myFormGroup.invalid) {
// stop here if it's invalid
alert('Invalid input');
return;
}
this.myDataService.submitUpdate(this.myFormGroup.getRawValue())
.subscribe((): void => {
alert('Saved!');
});
}
所有这些技术消除了对任何 [(ngModel)]
绑定的需求,因为表单在 FormGroup
对象内维护了自己的内部模型.
All these techniques eliminate the need for any [(ngModel)]
bindings, since the form maintains its own internal model inside the FormGroup
object.