There are two approaches to handling user input through forms:
- Template-driven forms
- Reactive forms (Model-driven forms)
When to Use Template-driven Forms:
- Small, simple forms (e.g., login or contact forms).
- Applications where form logic is mostly declarative.
- Quick prototyping or forms with minimal dynamic behavior.
When to Use Reactive Forms:
- Complex forms with dynamic behavior (e.g., adding/removing form fields).
- Forms that require more control over validation and state management.
- Larger applications where you need more scalability, flexibility, and reusability.
Both approaches have their strengths and should be chosen based on the complexity and requirements of the form you are building!
Key Differences between Template-driven and Reactive Forms:
-
Declarative vs Programmatic:
- Template-driven: Forms are defined directly in the HTML with Angular directives (like
ngModel
). - Reactive: Forms are defined in the component using Angular’s
FormControl
,FormGroup
, andFormBuilder
.
- Template-driven: Forms are defined directly in the HTML with Angular directives (like
-
Two-way Binding:
- Template-driven: Uses two-way data binding (
[(ngModel)]
). - Reactive: Does not require two-way binding, as values are handled using form controls and the component logic.
- Template-driven: Uses two-way data binding (
-
Validation:
- Template-driven: Validation is handled mostly in the template.
- Reactive: Validation is handled explicitly in the component, offering more flexibility.
-
Dynamic Forms:
- Template-driven: More static; not ideal for dynamic form changes.
- Reactive: Easier to add/remove form controls dynamically.
-
Control and Flexibility:
- Template-driven: Easier for small forms but less flexible.
- Reactive: More control and suitable for complex or large forms.
1. Template-driven Forms Example:
Template-driven forms are simple to set up and are useful for simpler forms where you don’t need as much flexibility.
Example (Template-driven form for a login or contact form):
app.component.html
:
<form #myForm="ngForm" (ngSubmit)="onSubmit(myForm)">
<label for="name">Name:</label>
<input type="text" id="name" name="name" [(ngModel)]="name" required />
<button type="submit" [disabled]="!myForm.valid">Submit</button>
</form>
<p *ngIf="submittedName">You submitted: {{ submittedName }}</p>
app.component.ts
:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
name: string = '';
submittedName: string = '';
onSubmit(form: any): void {
if (form.valid) {
this.submittedName = this.name;
}
}
}
Explanation:
- The form is built using HTML with Angular’s
ngModel
directive for two-way data binding. #myForm="ngForm"
binds the form to a local variable (myForm
), allowing you to access form validity and other properties.- On submission (
ngSubmit
), we check the form’s validity and set thesubmittedName
to the value of thename
field.
2. Reactive Forms Example:
Reactive forms provide more control over the form, including custom validations, dynamic form controls, and better scalability for complex forms.
Example (Reactive form with validation):
app.component.html
:
<form [formGroup]="nameForm" (ngSubmit)="onSubmit()">
<label for="name">Name:</label>
<input id="name" formControlName="name" />
<button type="submit" [disabled]="nameForm.invalid">Submit</button>
</form>
<p *ngIf="submittedName">You submitted: {{ submittedName }}</p>
app.component.ts
:
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
nameForm: FormGroup;
submittedName: string = '';
constructor(private fb: FormBuilder) {}
ngOnInit(): void {
this.nameForm = this.fb.group({
name: ['', Validators.required] // 'name' is required
});
}
onSubmit(): void {
if (this.nameForm.valid) {
this.submittedName = this.nameForm.value.name;
}
}
}
Explanation:
- In reactive forms, the form model is created in the component class using Angular’s
FormGroup
andFormControl
from@angular/forms
. formGroup
binds the form in the template to the component model, andformControlName
binds individual input elements to form controls.- The form is validated in the component using the
Validators
class to specify that thename
field is required.