Codecademy Logo

Angular Data Binding and Directives

Data Binding In Angular

In Angular, a component’s data model is linked to its template through various data binding methods, such as text interpolation and event binding.

<h1>Welcome {{ user.name }}</h1>
<button (click)="deactivate()">Deactivate</button>

Angular Directives

In Angular, the Document Object Model (DOM) can be augmented through various types of directives like component, attribute, and structural directives.

<!-- Use component directive-->
<app-user />

Two-way Data Binding in Angular

In Angular, two-way data binding enables a bi-directional flow of data between a component’s model and its template.

This type of binding uses a syntax that combines property and event binding, known as “banana-in-a-box.”

<!-- Two-way bind `toggle` to `user.active` property -->
<app-toggle [(toggle)]="user.activate"/>

Built-in Directives in Angular

Angular provides built-in attributes and structural directives to augment the DOM.

The attribute directives include:

  • ngClass: modifies the set of CSS classes applied to an element
  • ngStyle: modifies the set of styles applied to an element

The structural directives include:

  • ngIf: conditionally displays an element based on some condition
  • ngFor: displays an element in the DOM for every item in a list
  • ngSwitch: conditionally displays an element depending on some condition out of a set of conditions
<!-- modify class based on `user.active` -->
<h1 [ngClass]="user.active? 'active': 'deactivated'">Welcome {{ user.id }}</h1>

Custom Directives in Angular

A custom directive can be created in Angular using the @Directive (from @angular/core) decorator around a class, similar to creating a component.

The directive can accept an input by defining an input using @Input with the same name as the selector.

import { Directive, Input } from "@angular/core"
@Directive({
selector: "[appRotate]", // custom attribute selector
standalone: true
})
export class AppRotateDirective {
@Input() appRotate = "180deg" // rotation amount
}

Pipes in Angular

In Angular, pipes are used in a component’s template to apply a transformation to data. It is applied using a pipe symbol (|), and can be displayed and chained together. Angular provides many pre-built pipes like:

  • UpperCasePipe: formats data into all capital letters
  • DatePipe: formats dates
  • DecimalPipe: formates decimals
<!-- using a `DatePipe` to format the `user.joinedOn` `Date` object -->
<p>Joined {{ user.joinedOn | date }}</p>

Custom Pipes in Angular

A custom pipe can be created in Angular by creating a class decorated with @Pipe (from @angular/core). This class should implement the PipeTransform interface (from @angular/core) and its transform() method, which takes a value parameter and any number of other parameters.

import { Pipe, PipeTransform } from "@angular/core"
@Pipe({
name: "alternatecase", // name used in the template
standalone: true
})
export class AlternatingCasePipe implements PipeTransform {
transform(value: string, startUppercase = true): string { // value and other parameters
// implementation
}
}

Angular Event Binding

Angular provides a type of data binding used to synchronize data changes in the component’s template (through events) to the component’s data model, known as event binding.

Event binding involves wrapping a target event in parentheses (()) and calling an event handler function.

The event handler function can receive the Event object using the special $event argument.

<!-- event bind to `click` event and call `deactiveUser()` with the `Event` object through `$event` -->
<button (click)="deactivateUser($event)">Deactivate</button>

Host Listeners in Angular

In Angular, a host element can have its raised events bound using the @HostListener decorator from @angular/core. It allows components to react to host element events without directly manipulating the DOM.

@HostListener() takes two arguments:

  1. the name of the event to listen to, like 'click'
  2. a list of potential arguments, like the Event object emitted and other potential arguments
import { Component, HostListener } from "@angular/core"
@Component({
selector: "app-activate-button",
standalone: true
})
export class AppActivateButton {
@HostListener('click', ['$event']) // host bind to `click` event and receive `Event` object
handleClickEvent(event: Event) { // receives `Event` object and other potential args
// process click event
}
}

Angular Property Binding

Angular provides a type of data binding known as property binding, which allows you to bind a component’s data model to attributes of elements in the template. This one-way data binding ensures that whenever the source property in the component changes, the corresponding property in the template is automatically updated.

Property binding involves wrapping an element property in brackets ([]) and setting it equal to data in the component.

<!-- property bind the `user` property to an instance variable in the component called `selectedUser` -->
<app-user [user]="selectedUser"/>

Angular Text Interpolation

In Angular, text interpolation embeds data or expressions into text in the component’s template. This allows you to display component properties dynamically within the HTML.

Text interpolation is done by wrapping data in double curly braces ({{}}).

<!-- text interpolate `user.name` in the template text within the <p> element -->
<p>Welcome {{ user.name }}</p>

Creating Two-way Bindable Properties in Angular

A two-way bindable property can be created in an Angular component by defining an input property and an output property.

Use the @Input decorator to create an instance variable, allowing the parent component to pass data to this component.

Use the @Output decorator to create an instance variable with an EventEmitter. This variable should follow the naming pattern of the input property with “Change” appended to it, enabling the component to emit changes back to the parent.

In the example code, the @Input decorator is named isActive and the @Output decorator is named isActiveChange.

import { Component, Input, Output, EventEmitter } from "@angular/core"
@Component({
selector: "app-activate-button",
standalone: true
})
export class AppActivateButton {
// define input named `isActive`
@Input() isActive = false
// define output following `xChange` naming convention
@Output() isActiveChange = new EventEmitter<boolean>()
}

Host Elements in Angular

In Angular, a host element is the Document Object Model (DOM) element created to encapsulate a component’s template when the component instance is created.

Host elements contain the component’s template elements or the element a directive is attached to. In the code example, <app-dashboard> is the host element.

<!-- in `app-dashboard.component.html` -->
<!-- wrapped by `<app-dashboard>` when component instance is created -->
<h1>Welcome</h1>
<app-user/>
<footer>Thank You</footer>

Host Binding in Angular

In Angular, a host element can have its properties or attributes bound using the @HostBinding decorator from @angular/core. This is useful for dynamically setting classes, styles, or other attributes on the host element.

@HostBinding() takes a single argument, which is the name of an attribute or property to bind to, and the decorated variable or method provides its value.

import { Component, HostBinding, Input } from "@angular/core"
@Component({
selector: "app-activate-button",
standalone: true
})
export class AppActivateButton {
@Input() active = false
@HostBinding("class") // bind to `class`
myClass = "text-class" // `myClass` provides the value
@HostBinding("aria-label") // bind to `aria-label`
getLabel() {
return this.active? "activated" : "deactivated" // calculate `aria-label` for host element
}
}

Learn More on Codecademy