Angular 2 表单

Angular 2 提供了两种方式来处理表单数据:模板驱动表单响应式表单。这两种方法都支持双向数据绑定、表单验证和提交等功能,但它们的实现方式不同,适用于不同的场景。


1. 模板驱动表单 (Template-driven Forms)

模板驱动表单是一种简单的表单方式,主要通过模板中的 ngModel 指令来绑定数据。它适用于表单比较简单的情况。模板驱动表单使用 Angular 的内置指令如 ngModelngForm 等。

基本步骤

  1. 导入 FormsModule
  2. 使用 ngModel 指令进行双向数据绑定。
  3. 使用 ngForm 来管理表单的状态。
  4. 在模板中添加验证和提交表单。

示例:模板驱动表单

import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';

@Component({
  selector: 'app-root',
  template: `
    <form #myForm="ngForm" (ngSubmit)="onSubmit(myForm)">
      <div>
        <label for="username">Username:</label>
        <input type="text" id="username" name="username" [(ngModel)]="username" required>
        <div *ngIf="myForm.submitted && !username">Username is required.</div>
      </div>

      <div>
        <label for="email">Email:</label>
        <input type="email" id="email" name="email" [(ngModel)]="email" required>
      </div>

      <button type="submit" [disabled]="!myForm.valid">Submit</button>
    </form>
  `
})
export class AppComponent {
  username = '';
  email = '';

  onSubmit(form) {
    console.log('Form submitted', form.value);
  }
}

在这个例子中:

  • 使用 [(ngModel)] 双向绑定了表单控件和组件的属性。
  • ngSubmit 用于处理表单提交事件。
  • ngForm 通过 #myForm="ngForm" 引用表单,方便进行验证和管理表单的状态。

注意:模板驱动表单需要在应用的 app.module.ts 中导入 FormsModule

import { FormsModule } from '@angular/forms';

@NgModule({
  imports: [FormsModule],
  // other configurations...
})
export class AppModule { }


2. 响应式表单 (Reactive Forms)

响应式表单适用于复杂表单,提供更强大的功能和灵活性。它是通过组件类中的 FormGroupFormControl 来管理表单的。

响应式表单有更高的可测试性,适合表单动态生成、复杂验证和异步操作等场景。

基本步骤

  1. 导入 ReactiveFormsModule
  2. 在组件类中创建 FormGroupFormControl
  3. 使用 formGroupformControlName 在模板中绑定表单控件。

示例:响应式表单

import { Component } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'app-root',
  template: `
    <form [formGroup]="myForm" (ngSubmit)="onSubmit()">
      <div>
        <label for="username">Username:</label>
        <input id="username" formControlName="username">
        <div *ngIf="myForm.controls['username'].invalid && myForm.controls['username'].touched">
          Username is required.
        </div>
      </div>

      <div>
        <label for="email">Email:</label>
        <input id="email" formControlName="email">
        <div *ngIf="myForm.controls['email'].invalid && myForm.controls['email'].touched">
          Please enter a valid email.
        </div>
      </div>

      <button type="submit" [disabled]="myForm.invalid">Submit</button>
    </form>
  `
})
export class AppComponent {
  myForm = new FormGroup({
    username: new FormControl('', Validators.required),
    email: new FormControl('', [Validators.required, Validators.email])
  });

  onSubmit() {
    console.log('Form submitted', this.myForm.value);
  }
}

在这个例子中:

  • FormGroup 用于表示整个表单,FormControl 用于表示表单中的每个字段。
  • Validators.requiredValidators.email 用于验证输入值。
  • 通过 [formGroup][formControlName] 在模板中绑定数据。

注意:响应式表单需要在应用的 app.module.ts 中导入 ReactiveFormsModule

import { ReactiveFormsModule } from '@angular/forms';

@NgModule({
  imports: [ReactiveFormsModule],
  // other configurations...
})
export class AppModule { }


3. 表单验证 (Form Validation)

Angular 2 表单提供了强大的表单验证功能,可以使用内置验证器(如 requiredminlengthmaxlength 等)和自定义验证器来验证用户输入。

示例:表单验证

import { Component } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'app-root',
  template: `
    <form [formGroup]="myForm" (ngSubmit)="onSubmit()">
      <div>
        <label for="username">Username:</label>
        <input id="username" formControlName="username">
        <div *ngIf="myForm.controls['username'].invalid && myForm.controls['username'].touched">
          Username is required and must be at least 3 characters long.
        </div>
      </div>

      <div>
        <label for="email">Email:</label>
        <input id="email" formControlName="email">
        <div *ngIf="myForm.controls['email'].invalid && myForm.controls['email'].touched">
          Please enter a valid email.
        </div>
      </div>

      <button type="submit" [disabled]="myForm.invalid">Submit</button>
    </form>
  `
})
export class AppComponent {
  myForm = new FormGroup({
    username: new FormControl('', [Validators.required, Validators.minLength(3)]),
    email: new FormControl('', [Validators.required, Validators.email])
  });

  onSubmit() {
    console.log('Form submitted', this.myForm.value);
  }
}

在这个例子中:

  • Validators.required 确保字段必须填写。
  • Validators.minLength(3) 确保用户名至少有 3 个字符。
  • Validators.email 确保电子邮件地址的格式正确。
  • *ngIf 用于显示验证错误信息。

4. 动态表单控件

有时我们需要根据某些条件动态添加或删除表单控件。响应式表单使得这一操作非常简单。

示例:动态表单控件

import { Component } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';

@Component({
  selector: 'app-root',
  template: `
    <form [formGroup]="myForm">
      <div>
        <label for="username">Username:</label>
        <input id="username" formControlName="username">
      </div>

      <div *ngIf="isAgeFieldVisible">
        <label for="age">Age:</label>
        <input id="age" formControlName="age">
      </div>

      <button (click)="addAgeField()">Add Age Field</button>
      <button (click)="removeAgeField()">Remove Age Field</button>
      <button (click)="submitForm()">Submit</button>
    </form>
  `
})
export class AppComponent {
  myForm = new FormGroup({
    username: new FormControl(''),
  });

  isAgeFieldVisible = false;

  addAgeField() {
    this.myForm.addControl('age', new FormControl(''));
    this.isAgeFieldVisible = true;
  }

  removeAgeField() {
    this.myForm.removeControl('age');
    this.isAgeFieldVisible = false;
  }

  submitForm() {
    console.log(this.myForm.value);
  }
}

在这个例子中,addAgeField()removeAgeField() 方法分别动态添加和移除 age 控件。


总结

Angular 2 提供了两种主要的表单处理方式:

  1. 模板驱动表单:通过模板中的 ngModel 和内置指令进行表单处理,适用于简单的表单。
  2. 响应式表单:通过 FormGroupFormControl 在组件中管理表单,更适合复杂表单和动态表单。

无论使用哪种方式,Angular 都提供了丰富的表单验证功能和事件处理机制,帮助开发者轻松管理表单数据和用户输入。