Template-driven Forms คือฟอร์มที่กำหนด logic หลักใน Template ด้วย ngModel ส่วน Reactive Forms คือฟอร์มที่สร้างและควบคุมจาก Component Class เหมาะกับงานซับซ้อนและทดสอบง่ายกว่า
%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#fabd2f", "primaryTextColor": "#282828", "primaryBorderColor": "#b57614", "lineColor": "#7c6f64", "secondaryColor": "#83a598", "tertiaryColor": "#b8bb26", "background": "#fbf1c7", "mainBkg": "#ebdbb2", "fontFamily": "Tahoma, sans-serif"}}}%%
flowchart LR
subgraph Era1["ยุค HTML Form / Native Form"]
A["input + submit
ตรวจพื้นฐานใน Browser"]
end
subgraph Era2["ยุค Template Form / Simple Angular Form"]
B["ngModel
เขียนง่ายใน Template"]
end
subgraph Era3["ยุค Reactive Form / Complex Form"]
C["FormGroup/FormControl
ควบคุมใน Class"]
D["Dynamic Form
สร้างฟอร์มตามข้อมูล"]
end
A --> B --> C --> D
ngModel ใน Templatevalid, invalid, dirty, pristine, touched, untouched| หัวข้อ | Template-driven Forms | Reactive Forms |
|---|---|---|
| จุดควบคุมหลัก | Template | Component Class |
| ความง่าย | ง่ายกว่า | ต้องเขียนโค้ดมากกว่า |
| ฟอร์มซับซ้อน | ไม่เหมาะมาก | เหมาะมาก |
| Unit Test | ยากกว่า | ง่ายกว่า |
| Dynamic Form | จำกัด | ยืดหยุ่น |
| Module | FormsModule |
ReactiveFormsModule |
%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#fabd2f", "primaryTextColor": "#282828", "primaryBorderColor": "#b57614", "lineColor": "#7c6f64", "secondaryColor": "#83a598", "tertiaryColor": "#b8bb26", "background": "#fbf1c7", "mainBkg": "#ebdbb2", "fontFamily": "Tahoma, sans-serif"}}}%%
flowchart TD
A["ต้องสร้างฟอร์ม?
Need form?"] --> B{"ซับซ้อนหรือ Dynamic?
Complex or dynamic?"}
B -->|ไม่ / No| C["Template-driven
ngModel"]
B -->|ใช่ / Yes| D["Reactive Forms
FormGroup"]
D --> E["Validators + Unit Test
ตรวจง่าย"]
C --> F["FormsModule
ตั้งค่าง่าย"]
// app.module.ts
// import module ให้ตรงกับชนิดฟอร์มที่ใช้
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
@NgModule({
imports: [
FormsModule,
ReactiveFormsModule
]
})
export class AppModule {}
<!-- template-driven example -->
<!-- ใช้ ngModel และ name เพื่อให้ Angular ติดตามค่า input -->
<form #loginForm="ngForm" (ngSubmit)="submitTemplate(loginForm.value)">
<input name="email" ngModel required email>
<button type="submit" [disabled]="loginForm.invalid">Login</button>
</form>
// reactive-form example
// สร้าง FormGroup ใน Component Class
import { Component } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-login-reactive',
template: `
<form [formGroup]="loginForm" (ngSubmit)="submitReactive()">
<input formControlName="email">
<p *ngIf="loginForm.controls.email.touched && loginForm.controls.email.invalid">
กรุณากรอกอีเมลให้ถูกต้อง
</p>
<button type="submit" [disabled]="loginForm.invalid">Login</button>
</form>
`
})
export class LoginReactiveComponent {
loginForm = new FormGroup({
email: new FormControl('', [Validators.required, Validators.email])
});
submitReactive(): void {
console.log(this.loginForm.value);
}
}
// ตัวอย่างการใช้งาน:
// Reactive form เหมาะเมื่ออยากตรวจค่าหรือทดสอบ logic ใน TypeScript