Angular 响应式表单应用显式的、不可变的形式,治理表单在特定的工夫点上的状态。对表单状态的每一次变更都会返回一个新的状态,这样能够在变动时保护模型的整体性。响应式表单是围绕 Observable 流构建的,表单的输出和值都是通过这些输出值组成的流来提供的,它能够同步拜访。
响应式表单通过对数据模型的同步拜访提供了更多的可预测性,应用 Observable 的操作符提供了不可变性,并且通过 Observable 流提供了变动追踪性能。
要应用响应式表单控件,就要从 @angular/forms 包中导入 ReactiveFormsModule,并把它增加到你的 NgModule 的 imports 数组中。
import {ReactiveFormsModule} from '@angular/forms';
而后,生成一个新的 FormControl 实例,并把它保留在组件中。
要注册一个表单控件,就要导入 FormControl 类并创立一个 FormControl 的新实例,将其保留为类的属性。
import {Component} from '@angular/core';
import {FormControl} from '@angular/forms';
@Component({
selector: 'app-name-editor',
templateUrl: './name-editor.component.html',
styleUrls: ['./name-editor.component.css']
})
export class NameEditorComponent {name = new FormControl('');
}
通过在你的组件类中创立这些控件,你能够间接对表单控件的状态进行监听、批改和校验。
到当初为止,咱们只是在 Component 里创立了一个 FormControl 并把它赋给 Component 类的实例。然而,Component 的模板还感知不到这个 FormControl.
咱们须要批改 Component 模板文件,将模板里某个控件同 Component FormControl 实例绑定起来。
<label for="name">Name: </label>
<input id="name" type="text" [formControl]="name">
绑定的语法:
[formControl]="<Component 中用来保留 formControl 的类实例 >"
应用这种模板绑定语法,把该表单控件注册给了模板中名为 name 的输出元素。这样,表单控件和 DOM 元素就能够相互通信了:视图会反映模型的变动,模型也会反映视图中的变动。
这个通信是双向的。
有时在理论开发中,咱们还能看到 FormGroup 的应用例子:
Form Group 即表单组,定义了一个带有一组控件的表单,你能够把它们放在一起治理。
就像 FormControl 的实例能让你管制单个输入框所对应的控件一样,FormGroup 的实例也能跟踪一组 FormControl 实例(比方一个表单)的表单状态。当创立 FormGroup 时,其中的每个控件都会依据其名字进行跟踪。
看一个 FormGroup 创立例子:
import {Component} from '@angular/core';
import {FormGroup, FormControl} from '@angular/forms';
@Component({
selector: 'app-profile-editor',
templateUrl: './profile-editor.component.html',
styleUrls: ['./profile-editor.component.css']
})
export class ProfileEditorComponent {
profileForm = new FormGroup({firstName: new FormControl(''),
lastName: new FormControl(''),
});
}
当初,这些独立的表单控件被收集到了一个控件组中。这个 FormGroup 用对象的模式提供了它的模型值,这个值来自组中每个控件的值。FormGroup 实例领有和 FormControl 实例雷同的属性(比方 value、untouched)和办法(比方 setValue())。
咱们仍需将这个 FormGroup 实例关联到模板文件里。
这个表单组还能跟踪其中每个控件的状态及其变动,所以如果其中的某个控件的状态或值变动了,父控件也会收回一次新的状态变更或值变更事件。该控件组的模型来自它的所有成员。在定义了这个模型之后,你必须更新模板,来把该模型反映到视图中。
<form [formGroup]="profileForm">
<label for="first-name">First Name: </label>
<input id="first-name" type="text" formControlName="firstName">
<label for="last-name">Last Name: </label>
<input id="last-name" type="text" formControlName="lastName">
</form>
留神,就像 FormGroup 所蕴含的那控件一样,profileForm 这个 FormGroup 也通过 FormGroup 指令绑定到了 form 元素,在该模型和表单中的输入框之间创立了一个通信层。由 FormControlName 指令提供的 formControlName 属性把每个输入框和 FormGroup 中定义的表单控件绑定起来。这些表单控件会和相应的元素通信,它们还把更改传给 FormGroup,这个 FormGroup 是模型值的事实之源。
当然,理论开发中有另外一种实现办法:
先创立一个空的 FormGroup,再把后续创立的 FormControl 实例,而后通过 setControl 设置到 formGroup 里。
protected buildForm() {const form = new FormGroup({});
form.setControl('product', new FormControl(null));
this.form = form;
}
模板文件的实现:
<form [formGroup]="form" class="quick-order-form-container">
<div class="quick-order-form-input">
<input
formControlName="product"
placeholder="{{'quickOrderForm.placeholder'| cxTranslate}}"
type="text"
/>
更多 Jerry 的原创文章,尽在:” 汪子熙 ”: