模板驅動表單

很像 Vue 的 v-model,直接在模板中進行雙向綁定

1. 設置模板驅動表單模組

首先,需要引入 FormsModule:

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

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [FormsModule],  // 引入模板驅動表單模組
  template: `
    <form>
      <label>Name
        <input type="text" />
      </label>
      <label>Email
        <input type="email" />
      </label>
      <button type="submit">Submit</button>
    </form>
  `
})

2. 創建數據模型

在組件類中定義數據模型:

export class AppComponent {
  profile = {
    name: '',
    email: ''
  };
}

3. 使用 ngModel 進行雙向綁定

在模板中使用 ngModel:

@Component({
  template: `
    <form #profileForm="ngForm" (ngSubmit)="onSubmit(profileForm)">
      <label>
        Name
        <input 
          type="text" 
          name="name"
          [(ngModel)]="profile.name" 
        />
      </label>
      <label>
        Email
        <input 
          type="email" 
          name="email"
          [(ngModel)]="profile.email" 
        />
      </label>
      <button type="submit">Submit</button>
    </form>
  `
})

4. 顯示表單數據

直接在模板中使用綁定的數據:

@Component({
  template: `
    <h2>Profile Form</h2>
    <form #profileForm="ngForm">
      <!-- 表單控件 -->
    </form>
    
    <!-- 顯示表單數據 -->
    <p>Name: {{ profile.name }}</p>
    <p>Email: {{ profile.email }}</p>
  `
})

5. 處理表單提交

在組件類中添加提交處理方法:

export class AppComponent {
  profile = {
    name: '',
    email: ''
  };

  onSubmit(form: NgForm) {
    if (form.valid) {
      console.log('Form submitted', this.profile);
      alert(this.profile.name + ' | ' + this.profile.email);
    }
  }
}

重要概念說明

  1. ngModel

    • 實現雙向數據綁定

    • 需要設置 name 屬性

    • 使用 [(ngModel)] 語法

  2. #profileForm="ngForm"

    • 創建表單引用

    • 可以訪問表單狀態

    • 用於驗證和提交

  3. 表單驗證指令

    • required:必填字段

    • email:郵箱格式驗證

    • minlength:最小長度

    • pattern:正則表達式驗證

  4. 表單狀態

    • valid:表單是否有效

    • touched:是否被觸碰過

    • dirty:是否被修改過

常用表單驗證示例

<input 
  type="text" 
  name="name"
  [(ngModel)]="profile.name"
  required
  minlength="4"
  #name="ngModel"
>

<div *ngIf="name.invalid && (name.dirty || name.touched)">
  <div *ngIf="name.errors?.['required']">
    Name is required.
  </div>
  <div *ngIf="name.errors?.['minlength']">
    Name must be at least 4 characters long.
  </div>
</div>

Last updated