100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
TypeScript

Template-Driven Forms

Explore Angular's template-driven forms approach, where form structure and validation rules live mostly in the HTML template using directives like ngModel and ngForm.

Forms in AngularBeginner8 min readJul 9, 2026
Analogies

Template-Driven Forms

Angular offers two distinct approaches to building forms: template-driven and reactive. Template-driven forms, enabled by importing FormsModule, let you define most of the form's structure, bindings, and validation directly in the HTML template using directives such as ngModel, ngForm, and validation attributes like required and minlength. Angular automatically creates and manages an underlying form model (instances of NgModel, NgForm) behind the scenes based on what it finds in the template, which makes this style fast to write for simple forms but harder to unit test and less scalable for complex, dynamic, or highly validated forms compared to the reactive approach.

🏏

Cricket analogy: Template-driven forms are like a club match run entirely by the on-field captain's calls (the template), fast to organize for a casual game with FormsModule as the rulebook, but harder to formally scrutinize afterward than a fully documented reactive scorecard used in first-class cricket.

ngModel and Two-Way Binding

The core building block is [(ngModel)], Angular's banana-in-a-box syntax for two-way data binding, which keeps a template input element's value synchronized with a component property in both directions: typing in the field updates the property, and programmatically changing the property updates the field. Each ngModel-bound control must have a name attribute so Angular can register it with the enclosing NgForm instance, which aggregates every control's value and validity into a single form-level model.

🏏

Cricket analogy: [(ngModel)]'s two-way binding is like a live scoreboard synced both ways with the official scorebook: update the paper scorebook and the digital board changes, update the digital board and the scorebook reflects it, with each player's name tag registering them into the team sheet (NgForm).

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

interface SignupModel {
  email: string;
  password: string;
}

@Component({
  selector: 'app-signup',
  standalone: true,
  imports: [FormsModule],
  template: `
    <form #signupForm="ngForm" (ngSubmit)="onSubmit(signupForm)">
      <label>
        Email
        <input name="email" type="email" required email [(ngModel)]="model.email" #email="ngModel" />
      </label>
      @if (email.invalid && email.touched) {
        <p class="error">A valid email is required.</p>
      }

      <label>
        Password
        <input name="password" type="password" required minlength="8" [(ngModel)]="model.password" />
      </label>

      <button type="submit" [disabled]="signupForm.invalid">Sign up</button>
    </form>
  `,
})
export class SignupComponent {
  model: SignupModel = { email: '', password: '' };

  onSubmit(form: NgForm): void {
    if (form.valid) {
      console.log('Submitting', this.model);
    }
  }
}

Validation and Form State

Validation in template-driven forms is declared using HTML validation attributes (required, minlength, maxlength, pattern, plus Angular's own email directive), which Angular translates into validator functions internally. Each control exposes state via CSS classes (ng-valid, ng-invalid, ng-touched, ng-pristine, ng-dirty) that you can style directly, and via a template reference variable (e.g. #email="ngModel") that exposes properties like .invalid, .touched, and .errors for conditional messages in the template.

🏏

Cricket analogy: HTML validation attributes like required and minlength are like standard playing-condition rules written directly into the match regulations, with CSS classes like ng-invalid acting as a visible red card flag and a template reference variable like #email letting the scorer directly query a specific player's disciplinary status.

Template-driven forms are conceptually similar to how plain HTML forms or Vue's v-model work — binding is declared inline in markup — whereas Angular's reactive forms are closer to explicitly building a form model in code, similar to libraries like React Hook Form or Formik that construct the form's shape and validators in JavaScript/TypeScript rather than markup.

Because the form model in a template-driven form is built asynchronously by Angular as it processes the template, ngModel-related properties like signupForm.value are not reliably available inside ngOnInit — code that needs the form's initial state should instead react to it via the (ngSubmit) handler or subscribe to NgForm.valueChanges after the view has initialized.

  • Template-driven forms use [(ngModel)] and live mostly in the HTML template, requiring FormsModule to be imported.
  • Every ngModel-bound control needs a unique name attribute so it registers with the parent NgForm.
  • Validation is declared via HTML attributes like required, minlength, and Angular's email directive.
  • Form and control state (valid, touched, pristine, etc.) is exposed both as CSS classes and via template reference variables.
  • The underlying form model is built asynchronously by Angular, so it isn't reliably accessible in ngOnInit.
  • Template-driven forms suit simple forms; complex, dynamic, or heavily tested forms usually favor reactive forms instead.

Practice what you learned

Was this page helpful?

Topics covered

#TypeScript#AngularStudyNotes#WebDevelopment#TemplateDrivenForms#Template#Driven#Forms#NgModel#StudyNotes#SkillVeris