角度2反应形式与模板形式

时间:2017-06-15 02:19:07

标签: forms angular angular2-forms

我们正在开始一个新的Angular 2项目,并正在考虑是否使用Reactive Forms或Template Forms。阅读背景:https://angular.io/guide/reactive-forms

据我所知,Reactive Forms的最大优势在于它们是同步的,但我们有简单的形式,我不认为异步会导致我们的问题。 Reactive似乎有更多的开销,表面上有更多代码可以做同样的事情。

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

3 个答案:

答案 0 :(得分:52)

Template-driven vs Reactive Forms

这是我在Pluralsight中关于Forms的课程的幻灯片。其中一些观点可能是有争议的,但我与开发表格的Angular团队的人合作,将这个列表整理在一起。

答案 1 :(得分:3)

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

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

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

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

您可以通过以下两种方式的简单示例代码找到此解释: Introduction to Angular Forms - Template Driven vs Model Driven or Reactive Forms

答案 2 :(得分:0)

在幕后他们是相同的。以反应形式,这就是您在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实例。我们将在类组件中明确设置FormGroup和FormControl。

如果使用模板表单,则不会在parent.component.ts中设置任何内容。您可以在parent.component.html中编写代码。但是,此时,在幕后的角度仍然会创建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)]是两种方式的绑定。属性绑定和事件处理语法放在一起。如果类中的“电子邮件”值更改,则更新输入值,如果输入值更改,则同样更新类中的“电子邮件”。我们已经在类组件中定义了“电子邮件”

        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”。当角度看到此内容时,它将自动将其分配给Validator.required