繁体   English   中英

Angular 2 反应式表单与模板表单

[英]Angular 2 Reactive Forms vs Template Forms

我们正在启动一个新的 Angular 2 项目,并正在考虑是使用响应式表单还是模板表单。 背景阅读在这里: https : //angular.io/guide/reactive-forms

据我所知,Reactive Forms 的最大优点是它们是同步的,但是我们有简单的表单,我认为异步不会给我们带来问题。 Reactive 似乎有更多的开销,从表面上看,做同样事情的代码更多。

有人可以提供一个可靠的用例,我可以在更简单的模板表单上使用 Reactive 吗?

模板驱动与反应式表单

这是我的 Pluralsight 表单课程的幻灯片。 其中一些观点可能是有争议的,但我与来自 Angular 团队的开发 Forms 的人一起整理了这个列表。

模板驱动设计的优点是简单。 控制器中不会有太多代码。 大多数逻辑发生在模板中。 这适用于不需要 html 代码背后太多逻辑的简单表单。

但是每个表单都有一个状态,可以通过许多不同的交互进行更新,应用程序开发人员可以管理该状态并防止其损坏。 对于非常大的表单,这可能很难做到,并且可能会引入错误。

另一方面,如果需要更多的逻辑,通常也需要进行测试。 然后反应式模型驱动设计提供了更多。 我们可以对表单验证逻辑进行单元测试。 我们可以通过实例化类,在表单控件中设置一些值并执行测试来做到这一点。 对于复杂的软件,这是设计和可维护性绝对需要的。 反应式模型驱动设计的缺点是它的复杂性。

还有一种混合两种设计类型的方法,但这将具有两种类型的缺点。

您可以在此处使用两种方式的简单示例代码对此进行解释: Angular 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),
]), 

});

cardFormcardForm的一个实例。 我们需要将它连接到表单本身。

<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 实例。 我们在类组件中明确设置 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)] 是双向绑定。 属性绑定和事件处理语法放在一起。 如果类中的值“email”发生变化,则更新输入值,同样,如果输入值发生变化,则更新类中的“email”。 我们已经在类组件中定义了“电子邮件”

     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元素。 当 angular 看到这一点时,它会自动将其分配给Validator.required

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM