Skip to content
Angular Essentials
GitHub

Structural directives

Structural directive changes the DOM layout by adding and removing DOM elements.

Angular provides a set of built-in structural directives (such as NgIf, NgForOf, NgSwitch).

When structural directives are applied they generally are prefixed by an asterisk, *, such as *ngIf. This convention is a shorthand that Angular interprets and converts into a longer form. Angular transforms the asterisk in front of a structural directive into an ng-template element that surrounds the host element and its descendants.

In our CardComponent, let’s display the like count only if it is greater than 0.

<mat-card class="card">
  <mat-card-header>
    ...
    <mat-card-subtitle *ngIf="likeCount">{{likeCount}} Likes</mat-card-subtitle>
  </mat-card-header>
  ...
</mat-card>

Angular creates an element and applies the *ngIf directive onto it where it becomes a property binding in square brackets, [ngIf]. The rest of the mat-card-subtitle element, including its attribute, is then moved inside the ng-template element:

<ng-template [ngIf]="likeCount">
  <mat-card-subtitle>{{likeCount}} Likes</mat-card-subtitle>
</ng-template>

Angular does not actually create a real ng-template element, but instead only renders the mat-card-subtitle element.

Angular’s ng-template element defines a template that doesn’t render anything by default, if you just wrap elements in a ng-template without applying a structural directive those elements will not be rendered.

Likewise, let’s display multiple cards using *ngFor

export class CardComponent {
  ...
  titles: string[] = ['Maia', 'Dylan', 'Minoru', 'Amarachi', 'Ceallagh'];
  ...
}
<div class="card-container">
  <mat-card class="card" *ngFor="let cardTitle of titles">
    <mat-card-header>
      <mat-card-title>{{cardTitle}}</mat-card-title>
      ...
    </mat-card-header>
    ...
  </mat-card>
</div>