Skip to main content

Angular Templates

Introduction

Angular templates are a fundamental part of Angular applications. They are HTML files that tell Angular how to render the component's view. Unlike regular HTML, Angular templates are dynamic - they allow you to use special Angular syntax to create highly interactive user interfaces that can respond to changing data and user events.

In this lesson, we'll explore how Angular templates work, learn about their key features, and see how they empower you to build responsive, data-driven applications.

What Are Angular Templates?

At their core, Angular templates are HTML files with added Angular-specific syntax. They provide the view layer for Angular components. When an Angular application runs, the template rendering engine processes these templates and generates DOM (Document Object Model) that reflects the current state of your application.

A simple Angular template might look like this:

html
<div>
<h1>Hello, {{username}}!</h1>
<button (click)="greet()">Greet</button>
</div>

This template displays a greeting with a dynamic username and a button that triggers a method when clicked.

Key Features of Angular Templates

1. Interpolation

Interpolation allows you to embed expressions into marked up text. By default, interpolation uses double curly braces {{ }} as delimiters.

html
<h1>{{title}}</h1>
<p>My name is {{firstName}} {{lastName}}</p>
<p>The sum of 1 + 1 is {{1 + 1}}</p>

When the application runs, these expressions are replaced with their evaluated values. For example, if title is "My Angular App", Angular will render:

html
<h1>My Angular App</h1>

2. Property Binding

Property binding lets you set properties of target elements or directives. It uses square brackets [] syntax.

html
<img [src]="imageUrl" [alt]="imageAlt">
<button [disabled]="isDisabled">Click me</button>

In this example:

  • The src attribute of the <img> tag is bound to the imageUrl property of the component.
  • The disabled property of the button is bound to the isDisabled property of the component.

3. Event Binding

Event binding lets you listen for and respond to user events. It uses parentheses () syntax.

html
<button (click)="onSave()">Save</button>
<input (keyup)="onKeyUp($event)">

Here, when a user clicks the button, the onSave() method of the component is called. When the user types in the input field, the onKeyUp() method is called with the event object.

4. Two-way Binding

Two-way binding combines property binding and event binding. It uses the banana-in-a-box syntax [(ngModel)].

html
<input [(ngModel)]="name">
<p>Hello, {{name}}!</p>

When a user types in the input field, the name property in your component gets updated, and when the name property changes programmatically, the input field's value updates automatically.

note

To use ngModel, you need to import the FormsModule in your Angular module.

Directives in Templates

Directives are classes that add additional behavior to elements in your Angular applications. There are three types of directives in Angular:

1. Component Directives

Components are directives with a template. They are the most common type of directive.

html
<app-product-list></app-product-list>
<app-user-profile></app-user-profile>

2. Structural Directives

Structural directives alter the structure of the DOM by adding, removing, or manipulating elements. They have an asterisk (*) prefix.

ngIf

Shows or hides an element based on a condition:

html
<div *ngIf="isLoggedIn">
Welcome back, {{username}}!
</div>

<div *ngIf="!isLoggedIn">
Please log in to continue.
</div>

ngFor

Repeats a template for each item in a collection:

html
<ul>
<li *ngFor="let item of items; let i = index">
{{i + 1}}. {{item.name}}
</li>
</ul>

This will generate a list item for each element in the items array.

ngSwitch

Conditionally swaps the contents of an element based on a switch expression:

html
<div [ngSwitch]="userRole">
<div *ngSwitchCase="'admin'">Admin Panel</div>
<div *ngSwitchCase="'editor'">Editor Tools</div>
<div *ngSwitchDefault>User Dashboard</div>
</div>

3. Attribute Directives

Attribute directives change the appearance or behavior of an existing element. Common built-in attribute directives include:

ngClass

Adds and removes CSS classes:

html
<div [ngClass]="{'active': isActive, 'disabled': isDisabled}">
This div will have different classes based on component properties.
</div>

ngStyle

Sets inline styles:

html
<div [ngStyle]="{'color': textColor, 'font-size': fontSize + 'px'}">
This text has dynamic styling.
</div>

Pipes in Templates

Pipes transform displayed values within a template. Angular comes with several built-in pipes:

html
<p>The hero's birthday is {{ birthday | date }}</p>
<p>The hero's birthday is {{ birthday | date:'MM/dd/yyyy' }}</p>
<p>The price is {{ price | currency:'USD' }}</p>
<p>The message has {{ message | uppercase }}</p>

You can chain pipes and pass parameters to them:

html
<p>{{ dateObj | date:'fullDate' | uppercase }}</p>

Template Reference Variables

Template reference variables provide direct access to DOM elements in template. They are declared using a hash symbol (#):

html
<input #nameInput type="text">
<button (click)="greet(nameInput.value)">Greet</button>

Here, #nameInput creates a reference to the input element that can be used elsewhere in the template.

Practical Example: Todo List Application

Let's apply what we've learned by creating a simple todo list application template:

html
<div class="todo-app">
<h1>{{appTitle}}</h1>

<!-- Add new todo form -->
<form (submit)="addTodo()">
<input
[(ngModel)]="newTodoText"
name="newTodo"
placeholder="What needs to be done?"
#todoInput>
<button [disabled]="!newTodoText">Add</button>
</form>

<!-- Todo list -->
<div *ngIf="todos.length > 0; else emptyList">
<ul class="todo-list">
<li *ngFor="let todo of todos; let i = index" [ngClass]="{'completed': todo.completed}">
<input
type="checkbox"
[checked]="todo.completed"
(change)="toggleComplete(i)">
<span>{{ todo.text }}</span>
<button (click)="removeTodo(i)">Delete</button>
</li>
</ul>

<p>{{ todos.length }} item(s) left</p>

<!-- Filter buttons -->
<div class="filters">
<button
(click)="setFilter('all')"
[ngClass]="{'active': currentFilter === 'all'}">
All
</button>
<button
(click)="setFilter('active')"
[ngClass]="{'active': currentFilter === 'active'}">
Active
</button>
<button
(click)="setFilter('completed')"
[ngClass]="{'active': currentFilter === 'completed'}">
Completed
</button>
</div>
</div>

<!-- Empty state -->
<ng-template #emptyList>
<p>No todos yet! Add one to get started.</p>
</ng-template>
</div>

This template demonstrates:

  1. Interpolation to display the app title
  2. Two-way binding with [(ngModel)] for the new todo input
  3. Event binding with (submit) on the form and (click) on buttons
  4. Structural directives like *ngIf and *ngFor to control what's displayed
  5. Property binding with [disabled] on the add button
  6. Template reference variable with #todoInput
  7. Attribute directive with [ngClass] for styling

The corresponding component might look like:

typescript
import { Component } from '@angular/core';

interface Todo {
text: string;
completed: boolean;
}

@Component({
selector: 'app-todo-list',
templateUrl: './todo-list.component.html',
styleUrls: ['./todo-list.component.css']
})
export class TodoListComponent {
appTitle = 'My Todo List';
newTodoText = '';
todos: Todo[] = [];
currentFilter = 'all';

addTodo() {
if (this.newTodoText.trim()) {
this.todos.push({
text: this.newTodoText,
completed: false
});
this.newTodoText = '';
}
}

toggleComplete(index: number) {
this.todos[index].completed = !this.todos[index].completed;
}

removeTodo(index: number) {
this.todos.splice(index, 1);
}

setFilter(filter: string) {
this.currentFilter = filter;
}
}

Summary

Angular templates form the view layer of Angular applications, allowing you to create dynamic UIs that respond to data changes and user interactions. Key features include:

  • Interpolation ({{}}) for displaying component data in the template
  • Property binding ([]) to set element properties based on component data
  • Event binding (()) to respond to user events
  • Two-way binding ([()]) to create synchronized data flow
  • Directives for adding behavior and dynamically modifying the DOM
  • Pipes for transforming data for display
  • Template reference variables for easier access to DOM elements

By combining these features, you can create rich, interactive user experiences without having to manipulate the DOM directly.

Additional Resources

Exercises

  1. Create a simple form that collects user information (name, email, age) and displays it below the form when submitted.
  2. Build a product list page with filtering options that allows users to filter by category and sort by price.
  3. Create a dynamic navigation menu that highlights the current active route and shows/hides elements based on user permissions.
  4. Implement a custom pipe that formats phone numbers into a standard format (e.g., (123) 456-7890).
  5. Build a component that uses ngTemplateOutlet to reuse the same template with different data contexts.


If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)