Angular 2 响应式表单与模板表单
Angular 2 Reactive Forms vs Template Forms
我们正在开始一个新的 Angular 2 项目,并且正在考虑是使用 Reactive Forms 还是 Template Forms。背景阅读此处:https://angular.io/guide/reactive-forms
据我所知,Reactive Forms 的最大优点是它们是同步的,但我们有简单的表单,我认为异步不会给我们带来问题。 Reactive 似乎有更多的开销,表面上有更多的代码来做同样的事情。
有人可以提供一个可靠的用例,让我可以在更简单的模板表单上使用 Reactive 吗?
这是我的 Forms in Pluralsight 课程中的一张幻灯片。其中一些观点可能有争议,但我与开发表单的 Angular 团队的人员合作,将此列表放在一起。
模板驱动设计的优点是简单。控制器中不会有太多代码。大多数逻辑发生在模板中。这适用于在 html 代码背后不需要太多逻辑的简单表单。
但每个表单都有一个状态,可以通过许多不同的交互进行更新,应用程序开发人员需要管理该状态并防止其损坏。这对于非常大的表单来说很难做到,并且会引入错误。
另一方面,如果需要更多的逻辑,往往也需要进行测试。然后反应模型驱动设计提供更多。我们可以对表单验证逻辑进行单元测试。我们可以通过实例化 class、在表单控件中设置一些值并执行测试来做到这一点。对于复杂的软件,这是设计和可维护性所绝对需要的。反应模型驱动设计的缺点是它的复杂性。
还有一种混合两种设计类型的方法,但这会同时具有两种类型的缺点。
您可以在此处找到针对这两种方式的简单示例代码的解释:
Introduction to Angular Forms - Template Driven vs Model Driven or Reactive Forms
在幕后他们是一样的。在反应形式中,这就是你在 app.module.ts:
中导入的内容
import { ReactiveFormsModule } from '@angular/forms';
imports: [BrowserModule, ReactiveFormsModule],
然后在你的 parent.component.ts
import { FormGroup, FormControl, Validators } from '@angular/forms';
cardForm = new FormGroup({
name: new FormControl('', [
Validators.required,
Validators.minLength(3),
Validators.maxLength(5),
]),
});
cardForm
是 FormGroup 的一个实例。我们需要将它连接到表单本身。
<form [formGroup]="cardForm" (ngSubmit)="onSubmit()"></form>
这表示此表单将由“cardForm”处理。在表单的每个输入元素中,我们将添加控制器以监听所有更改并将这些更改传递给“cardForm”。
<form [formGroup]="cardForm" (ngSubmit)="onSubmit()">
<app-input label="Name" [control]="cardForm.get('name')"> </app-input>
</form>
cardForm.get('name')= new FormControl('initValue', [
Validators.required,
Validators.minLength(3),
Validators.maxLength(5),
]),
简而言之,FormControl 实例放置在输入元素中,它们监听所有变化并将它们报告给 FormGroup 实例。我们正在 class 组件中明确设置 FormGroup 和 FormControl。
如果您使用模板表单,则无需在 parent.component.ts 中设置任何内容。你在 parent.component.html 里面写你的代码。但是此时,angular幕后仍然会创建FormGroup,并通过FormGroup来处理表单。在 app.module.ts
import { FormsModule } from '@angular/forms';
imports: [BrowserModule, FormsModule],
我们没有为 FormGroup 和 FormControl 编写任何代码。我们转到模板文件:
<form (ngSubmit)="onSubmit()" #emailForm="ngForm">
#emailForm 创建对在后台创建的“FormGroup”的引用。这样我们就可以访问 FormGroup 的所有属性,例如“touched”、“valid”等。
然后我们将输入元素放在表单中:
<input
type="email"
required
name="email"
[(ngModel)]="email"
#emailControl="ngModel"
/>
ngModel 是指令。告诉 Angular,我们要跟踪此输入中的值。它会将大量事件处理程序附加到输入元素。
[(ngModel)] 是双向绑定。 属性 绑定和事件处理语法放在一起。如果 class 中的值“email”发生变化,则更新输入值,同样,如果输入值发生变化,则更新 class 中的“email”。我们已经在 class 组件
中定义了“电子邮件”
export class AppComponent {
email: string; // [(ngModel)] communicates with this
onSubmit() {
console.log(this.email);
}
}
#emailControl 是对输入控件的引用。名字可以是任何东西。
emailControl===emailForm.controls.email
所以在这个模板表单中,#emailForm
代表FormGroup,#emailControl
代表FormControl。
- 在响应式表单中,我们在 FormControl 中显式编写验证逻辑。但是对于模板,如果您检查
input
元素,我们会添加“required”。当angular看到这个,它会自动分配给Validator.required
我们正在开始一个新的 Angular 2 项目,并且正在考虑是使用 Reactive Forms 还是 Template Forms。背景阅读此处:https://angular.io/guide/reactive-forms
据我所知,Reactive Forms 的最大优点是它们是同步的,但我们有简单的表单,我认为异步不会给我们带来问题。 Reactive 似乎有更多的开销,表面上有更多的代码来做同样的事情。
有人可以提供一个可靠的用例,让我可以在更简单的模板表单上使用 Reactive 吗?
这是我的 Forms in Pluralsight 课程中的一张幻灯片。其中一些观点可能有争议,但我与开发表单的 Angular 团队的人员合作,将此列表放在一起。
模板驱动设计的优点是简单。控制器中不会有太多代码。大多数逻辑发生在模板中。这适用于在 html 代码背后不需要太多逻辑的简单表单。
但每个表单都有一个状态,可以通过许多不同的交互进行更新,应用程序开发人员需要管理该状态并防止其损坏。这对于非常大的表单来说很难做到,并且会引入错误。
另一方面,如果需要更多的逻辑,往往也需要进行测试。然后反应模型驱动设计提供更多。我们可以对表单验证逻辑进行单元测试。我们可以通过实例化 class、在表单控件中设置一些值并执行测试来做到这一点。对于复杂的软件,这是设计和可维护性所绝对需要的。反应模型驱动设计的缺点是它的复杂性。
还有一种混合两种设计类型的方法,但这会同时具有两种类型的缺点。
您可以在此处找到针对这两种方式的简单示例代码的解释: Introduction to Angular Forms - Template Driven vs Model Driven or Reactive Forms
在幕后他们是一样的。在反应形式中,这就是你在 app.module.ts:
中导入的内容import { ReactiveFormsModule } from '@angular/forms';
imports: [BrowserModule, ReactiveFormsModule],
然后在你的 parent.component.ts
import { FormGroup, FormControl, Validators } from '@angular/forms';
cardForm = new FormGroup({
name: new FormControl('', [
Validators.required,
Validators.minLength(3),
Validators.maxLength(5),
]),
});
cardForm
是 FormGroup 的一个实例。我们需要将它连接到表单本身。
<form [formGroup]="cardForm" (ngSubmit)="onSubmit()"></form>
这表示此表单将由“cardForm”处理。在表单的每个输入元素中,我们将添加控制器以监听所有更改并将这些更改传递给“cardForm”。
<form [formGroup]="cardForm" (ngSubmit)="onSubmit()">
<app-input label="Name" [control]="cardForm.get('name')"> </app-input>
</form>
cardForm.get('name')= new FormControl('initValue', [
Validators.required,
Validators.minLength(3),
Validators.maxLength(5),
]),
简而言之,FormControl 实例放置在输入元素中,它们监听所有变化并将它们报告给 FormGroup 实例。我们正在 class 组件中明确设置 FormGroup 和 FormControl。
如果您使用模板表单,则无需在 parent.component.ts 中设置任何内容。你在 parent.component.html 里面写你的代码。但是此时,angular幕后仍然会创建FormGroup,并通过FormGroup来处理表单。在 app.module.ts
import { FormsModule } from '@angular/forms';
imports: [BrowserModule, FormsModule],
我们没有为 FormGroup 和 FormControl 编写任何代码。我们转到模板文件:
<form (ngSubmit)="onSubmit()" #emailForm="ngForm">
#emailForm 创建对在后台创建的“FormGroup”的引用。这样我们就可以访问 FormGroup 的所有属性,例如“touched”、“valid”等。
然后我们将输入元素放在表单中:
<input
type="email"
required
name="email"
[(ngModel)]="email"
#emailControl="ngModel"
/>
ngModel 是指令。告诉 Angular,我们要跟踪此输入中的值。它会将大量事件处理程序附加到输入元素。
[(ngModel)] 是双向绑定。 属性 绑定和事件处理语法放在一起。如果 class 中的值“email”发生变化,则更新输入值,同样,如果输入值发生变化,则更新 class 中的“email”。我们已经在 class 组件
中定义了“电子邮件”export class AppComponent { email: string; // [(ngModel)] communicates with this onSubmit() { console.log(this.email); } }
#emailControl 是对输入控件的引用。名字可以是任何东西。
emailControl===emailForm.controls.email
所以在这个模板表单中,#emailForm
代表FormGroup,#emailControl
代表FormControl。
- 在响应式表单中,我们在 FormControl 中显式编写验证逻辑。但是对于模板,如果您检查
input
元素,我们会添加“required”。当angular看到这个,它会自动分配给Validator.required