Built-in directives link
Directives are classes that add additional behavior to elements in your Angular applications. Use Angular's built-in directives to manage forms, lists, styles, and what users see.
See the
The different types of Angular directives are as follows:
Directive Types | Details |
---|---|
Components | Used with a template. This type of directive is the most common directive type. |
Attribute directives | Change the appearance or behavior of an element, component, or another directive. |
Structural directives | Change the DOM layout by adding and removing DOM elements. |
This guide covers built-in attribute directives and structural directives.
Built-in attribute directives link
Attribute directives listen to and modify the behavior of other HTML elements, attributes, properties, and components.
Many NgModules such as the
RouterModule
and the
FormsModule
define their own attribute directives.
The most common attribute directives are as follows:
Common directives | Details |
---|---|
NgClass
|
Adds and removes a set of CSS classes. |
NgStyle
|
Adds and removes a set of HTML styles. |
NgModel
|
Adds two-way data binding to an HTML form element. |
Built-in directives use only public APIs. They do not have special access to any private APIs that other directives can't access.
Adding and removing classes with
NgClass
link
Add or remove multiple CSS classes simultaneously with
ngClass
.
To add or remove a
single
class, use class binding rather than
NgClass
.
Using
NgClass
with an expression
link
On the element you'd like to style, add
[ngClass]
and set it equal to an expression.
In this case,
isSpecial
is a boolean set to
true
in
app.component.ts
.
Because
isSpecial
is true,
ngClass
applies the class of
special
to the
<div>
.
<!-- toggle the "special" class on/off with a property -->
<div [ngClass]="isSpecial ? 'special' : ''">This div is special</div>
Using
NgClass
with a method
link
-
To use
NgClass
with a method, add the method to the component class. In the following example,setCurrentClasses()
sets the propertycurrentClasses
with an object that adds or removes three classes based on thetrue
orfalse
state of three other component properties.Each key of the object is a CSS class name. If a key is
true
,ngClass
adds the class. If a key isfalse
,ngClass
removes the class.src/app/app.component.ts currentClasses: Record<string, boolean> = {}; /* . . . */ setCurrentClasses() { // CSS classes: added/removed per current state of component properties this.currentClasses = { saveable: this.canSave, modified: !this.isUnchanged, special: this.isSpecial }; }
-
In the template, add the
ngClass
property binding tocurrentClasses
to set the element's classes:src/app/app.component.html <div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special.</div>
For this use case, Angular applies the classes on initialization and in case of changes.
The full example calls
setCurrentClasses()
initially with
ngOnInit()
and when the dependent properties change through a button click.
These steps are not necessary to implement
ngClass
.
For more information, see the
app.component.ts
and
app.component.html
.
Setting inline styles with
NgStyle
link
Use
NgStyle
to set multiple inline styles simultaneously, based on the state of the component.
-
To use
NgStyle
, add a method to the component class.In the following example,
setCurrentStyles()
sets the propertycurrentStyles
with an object that defines three styles, based on the state of three other component properties.src/app/app.component.ts currentStyles: Record<string, string> = {}; /* . . . */ setCurrentStyles() { // CSS styles: set per current state of component properties this.currentStyles = { 'font-style': this.canSave ? 'italic' : 'normal', 'font-weight': !this.isUnchanged ? 'bold' : 'normal', 'font-size': this.isSpecial ? '24px' : '12px' }; }
-
To set the element's styles, add an
ngStyle
property binding tocurrentStyles
.src/app/app.component.html <div [ngStyle]="currentStyles"> This div is initially italic, normal weight, and extra large (24px). </div>
For this use case, Angular applies the styles upon initialization and in case of changes.
To do this, the full example calls
setCurrentStyles()
initially with
ngOnInit()
and when the dependent properties change through a button click.
However, these steps are not necessary to implement
ngStyle
on its own.
See the
app.component.ts
and
app.component.html
for this optional implementation.
Displaying and updating properties with
ngModel
link
Use the
NgModel
directive to display a data property and update that property when the user makes changes.
-
Import
FormsModule
and add it to the NgModule'simports
list.src/app/app.module.ts (FormsModule import) import { FormsModule } from '@angular/forms'; // <--- JavaScript import from Angular /* . . . */ @NgModule({ /* . . . */ imports: [ BrowserModule, FormsModule // <--- import into the NgModule ], /* . . . */ }) export class AppModule { }
-
Add an
[(ngModel)]
binding on an HTML<form>
element and set it equal to the property, herename
.src/app/app.component.html (NgModel example) <label for="example-ngModel">[(ngModel)]:</label> <input [(ngModel)]="currentItem.name" id="example-ngModel">
This
[(ngModel)]
syntax can only set a data-bound property.
To customize your configuration, write the expanded form, which separates the property and event binding.
Use property binding to set the property and event binding to respond to changes.
The following example changes the
<input>
value to uppercase:
<input [ngModel]="currentItem.name" (ngModelChange)="setUppercaseName($event)" id="example-uppercase">
Here are all variations in action, including the uppercase version:
NgModel
and value accessors
link
The
NgModel
directive works for an element supported by a ControlValueAccessor.
Angular provides
value accessors
for all of the basic HTML form elements.
For more information, see Forms.
To apply
[(ngModel)]
to a non-form built-in element or a third-party custom component, you have to write a value accessor.
For more information, see the API documentation on DefaultValueAccessor.
When you write an Angular component, you don't need a value accessor or
NgModel
if you name the value and event properties according to Angular's two-way binding syntax.
Built-in structural directives link
Structural directives are responsible for HTML layout. They shape or reshape the DOM's structure, typically by adding, removing, and manipulating the host elements to which they are attached.
This section introduces the most common built-in structural directives:
Common built-in structural directives | Details |
---|---|
NgIf
|
Conditionally creates or disposes of subviews from the template. |
NgFor
|
Repeat a node for each item in a list. |
NgSwitch
|
A set of directives that switch among alternative views. |
For more information, see Structural Directives.
Adding or removing an element with
NgIf
link
Add or remove an element by applying an
NgIf
directive to a host element.
When
NgIf
is
false
, Angular removes an element and its descendants from the DOM.
Angular then disposes of their components, which frees up memory and resources.
To add or remove an element, bind
*ngIf
to a condition expression such as
isActive
in the following example.
<app-item-detail *ngIf="isActive" [item]="item"></app-item-detail>
When the
isActive
expression returns a truthy value,
NgIf
adds the
ItemDetailComponent
to the DOM.
When the expression is falsy,
NgIf
removes the
ItemDetailComponent
from the DOM and disposes of the component and all of its subcomponents.
For more information on
NgIf
and
NgIfElse
, see the NgIf API documentation.
Guarding against
null
link
By default,
NgIf
prevents display of an element bound to a null value.
To use
NgIf
to guard a
<div>
, add
*ngIf="yourProperty"
to the
<div>
.
In the following example, the
currentCustomer
name appears because there is a
currentCustomer
.
<div *ngIf="currentCustomer">Hello, {{currentCustomer.name}}</div>
However, if the property is
null
, Angular does not display the
<div>
.
In this example, Angular does not display the
nullCustomer
because it is
null
.
<div *ngIf="nullCustomer">Hello, <span>{{nullCustomer}}</span></div>
Listing items with
NgFor
link
Use the
NgFor
directive to present a list of items.
- Define a block of HTML that determines how Angular renders a single item.
-
To list your items, assign the shorthand
let item of items
to*ngFor
.
<div *ngFor="let item of items">{{item.name}}</div>
The string
"let item of items"
instructs Angular to do the following:
-
Store each item in the
items
array in the localitem
looping variable - Make each item available to the templated HTML for each iteration
-
Translate
"let item of items"
into an<ng-template>
around the host element -
Repeat the
<ng-template>
for eachitem
in the list
For more information see the Structural directive shorthand section of Structural directives.
Repeating a component view link
To repeat a component element, apply
*ngFor
to the selector.
In the following example, the selector is
<app-item-detail>
.
<app-item-detail *ngFor="let item of items" [item]="item"></app-item-detail>
Reference a template input variable, such as
item
, in the following locations:
-
Within the
ngFor
host element - Within the host element descendants to access the item's properties
The following example references
item
first in an interpolation and then passes in a binding to the
item
property of the
<app-item-detail>
component.
<div *ngFor="let item of items">{{item.name}}</div>
<!-- . . . -->
<app-item-detail *ngFor="let item of items" [item]="item"></app-item-detail>
For more information about template input variables, see Structural directive shorthand.
Getting the
index
of
*ngFor
link
Get the
index
of
*ngFor
in a template input variable and use it in the template.
In the
*ngFor
, add a semicolon and
let i=index
to the shorthand.
The following example gets the
index
in a variable named
i
and displays it with the item name.
<div *ngFor="let item of items; let i=index">{{i + 1}} - {{item.name}}</div>
The index property of the
NgFor
directive context returns the zero-based index of the item in each iteration.
Angular translates this instruction into an
<ng-template>
around the host element,
then uses this template repeatedly to create a new set of elements and bindings for each
item
in the list.
For more information about shorthand, see the Structural Directives guide.
Repeating elements when a condition is true link
To repeat a block of HTML when a particular condition is true, put the
*ngIf
on a container element that wraps an
*ngFor
element.
For more information see one structural directive per element.
Tracking items with
*ngFor
trackBy
link
Reduce the number of calls your application makes to the server by tracking changes to an item list.
With the
*ngFor
trackBy
property, Angular can change and re-render only those items that have changed, rather than reloading the entire list of items.
-
Add a method to the component that returns the value
NgFor
should track. In this example, the value to track is the item'sid
. If the browser has already renderedid
, Angular keeps track of it and doesn't re-query the server for the sameid
.src/app/app.component.ts trackByItems(index: number, item: Item): number { return item.id; }
-
In the shorthand expression, set
trackBy
to thetrackByItems()
method.src/app/app.component.html <div *ngFor="let item of items; trackBy: trackByItems"> ({{item.id}}) {{item.name}} </div>
Change ids
creates new items with new
item.id
s.
In the following illustration of the
trackBy
effect,
Reset items
creates new items with the same
item.id
s.
-
With no
trackBy
, both buttons trigger complete DOM element replacement. -
With
trackBy
, only changing theid
triggers element replacement.
Hosting a directive without a DOM element link
The Angular
<ng-container>
is a grouping element that doesn't interfere with styles or layout because Angular doesn't put it in the DOM.
Use
<ng-container>
when there's no single element to host the directive.
Here's a conditional paragraph using
<ng-container>
.
<p>
I turned the corner
<ng-container *ngIf="hero">
and saw {{hero.name}}. I waved
</ng-container>
and continued on my way.
</p>
-
Import the
ngModel
directive fromFormsModule
. -
Add
FormsModule
to the imports section of the relevant Angular module. -
To conditionally exclude an
<option>
, wrap the<option>
in an<ng-container>
.src/app/app.component.html (select-ngcontainer) <div> Pick your favorite hero (<label><input type="checkbox" checked (change)="showSad = !showSad">show sad</label>) </div> <select [(ngModel)]="hero"> <ng-container *ngFor="let h of heroes"> <ng-container *ngIf="showSad || h.emotion !== 'sad'"> <option [ngValue]="h">{{h.name}} ({{h.emotion}})</option> </ng-container> </ng-container> </select>
Switching cases with
NgSwitch
link
Like the JavaScript
switch
statement,
NgSwitch
displays one element from among several possible elements, based on a switch condition.
Angular puts only the selected element into the DOM.
NgSwitch
is a set of three directives:
NgSwitch
directives
|
Details |
---|---|
NgSwitch
|
An attribute directive that changes the behavior of its companion directives. |
NgSwitchCase
|
Structural directive that adds its element to the DOM when its bound value equals the switch value and removes its bound value when it doesn't equal the switch value. |
NgSwitchDefault
|
Structural directive that adds its element to the DOM when there is no selected
NgSwitchCase
.
|
-
On an element, such as a
<div>
, add[ngSwitch]
bound to an expression that returns the switch value, such asfeature
. Though thefeature
value in this example is a string, the switch value can be of any type. -
Bind to
*ngSwitchCase
and*ngSwitchDefault
on the elements for the cases.src/app/app.component.html <div [ngSwitch]="currentItem.feature"> <app-stout-item *ngSwitchCase="'stout'" [item]="currentItem"></app-stout-item> <app-device-item *ngSwitchCase="'slim'" [item]="currentItem"></app-device-item> <app-lost-item *ngSwitchCase="'vintage'" [item]="currentItem"></app-lost-item> <app-best-item *ngSwitchCase="'bright'" [item]="currentItem"></app-best-item> <!-- . . . --> <app-unknown-item *ngSwitchDefault [item]="currentItem"></app-unknown-item> </div>
-
In the parent component, define
currentItem
, to use it in the[ngSwitch]
expression.src/app/app.component.ts currentItem!: Item;
-
In each child component, add an
item
input property which is bound to thecurrentItem
of the parent component. The following two snippets show the parent component and one of the child components. The other child components are identical toStoutItemComponent
.In each child component, here StoutItemComponent export class StoutItemComponent { @Input() item!: Item; }
Switch directives also work with built-in HTML elements and web components.
For example, you could replace the
<app-best-item>
switch case with a
<div>
as follows.
<div *ngSwitchCase="'bright'"> Are you as bright as {{currentItem.name}}?</div>
What's next link
For information on how to build your own custom directives, see Attribute Directives and Structural Directives.