Diretivas Estruturais: ngIf, ngFor, ngSwitch em Angular
As diretivas estruturais no Angular permitem modificar a estrutura do DOM, adicionando ou removendo elementos HTML. Vamos explorar três diretivas estruturais: ngIf
, ngSwitch
e ngFor
.
ngIf
A diretiva ngIf
permite adicionar ou remover um elemento com base em uma condição específica. Por exemplo, considere o seguinte componente:
import { Component } from "@angular/core";
import { NgIf } from "@angular/common";
@Component({
selector: "my-app",
standalone: true,
imports: [NgIf],
template: `<p *ngIf="condition">Olá, mundo</p>
<p *ngIf="!condition">Adeus, mundo</p>
<button (click)="toggle()">Toggle</button>`,
})
export class AppComponent {
condition: boolean = true;
toggle() {
this.condition = !this.condition;
}
}
Para utilizar a diretiva, é necessário importar a classe NgIf
do pacote "@angular/common"
.
No template do componente, dependendo do valor da propriedade condition, será exibido o primeiro ou o segundo parágrafo.
Podemos definir expressões alternativas usando a diretiva ng-template
. Assim, o exemplo anterior pode ser reescrito da seguinte forma:
import { Component } from "@angular/core";
import { NgIf } from "@angular/common";
@Component({
selector: "my-app",
standalone: true,
imports: [NgIf],
template: `<p *ngIf="condition; else unset">Olá, mundo</p>
<ng-template #unset>
<p>Adeus, mundo</p>
</ng-template>
<button (click)="toggle()">Toggle</button>`,
})
export class AppComponent {
condition = true;
toggle() {
this.condition = !this.condition;
}
}
A expressão *ngIf="condition; else unset"
indica que, se condition for false, o bloco <ng-template #unset>
será executado.
Também podemos definir uma lógica mais sofisticada. Por exemplo, podemos alterar o template do componente da seguinte maneira:
template: `
<div *ngIf="condition; then thenBlock else elseBlock"></div>
<ng-template #thenBlock>Bloco then</ng-template>
<ng-template #elseBlock>Bloco else</ng-template>
<button (click)="toggle()">Toggle</button>`
Nesse caso, se condition for true
, o bloco thenBlock
será exibido; caso contrário, o bloco elseBlock
será mostrado.
ngFor
A diretiva ngFor
permite iterar sobre elementos de um array dentro do template. Por exemplo:
import { Component } from "@angular/core";
import { NgFor } from "@angular/common";
@Component({
selector: "my-app",
standalone: true,
imports: [NgFor],
template: `<ul>
<li *ngFor="let item of items">{{ item }}</li>
</ul>`,
})
export class AppComponent {
items = ["Tom", "Bob", "Sam", "Bill"];
}
A diretiva recebe uma expressão de iteração similar ao foreach
: let item of items
. Cada item iterado é armazenado na variável item
, que pode ser exibida na página.
Durante a iteração, o índice atual do item está disponível por meio da variável index
, que também pode ser utilizada. Por exemplo:
<div>
<p *ngFor="let item of items; let i = index">{{i+1}}. {{item}}</p>
</div>
Vale lembrar que a indexação começa em zero, por isso, para que a contagem inicie em um, adicionamos um ao valor da variável i
.
Símbolo de Asterisco e Açúcar Sintático
É possível notar que, ao utilizar as diretivas ngFor
e ngIf
, o símbolo de asterisco é colocado antes delas. Na verdade, isso é apenas um açúcar sintático que simplifica a aplicação da diretiva. Por exemplo, a definição de ngIf
:
<p *ngIf="condition">Olá, mundo</p>
<p *ngIf="!condition">Adeus, mundo</p>
Na verdade, representa o seguinte código:
<ng-template [ngIf]="condition">
<p>Olá, mundo</p>
</ng-template>
<ng-template [ngIf]="!condition">
<p>Adeus, mundo</p>
</ng-template>
Nesse caso, o parágrafo e seu texto são movidos para dentro do elemento <ng-template>
. A diretiva em si é aplicada ao elemento <ng-template>
, onde é utilizada uma vinculação de propriedade. O valor booleano da propriedade vinculada determina se o conteúdo correspondente deve ser exibido.
Podemos escolher entre o primeiro método, com o asterisco, que é mais compacto, ou o segundo, utilizando os elementos ng-template
.
O mesmo se aplica à diretiva ngFor
:
<ul>
<li *ngFor="let item of items">{{item}}</li>
</ul>
Esse código é equivalente ao seguinte:
<ul>
<ng-template ngFor let-item [ngForOf]="items">
<li>{{item}}</li>
</ng-template>
</ul>
ngSwitch
A diretiva ngSwitch
permite incluir no template uma construção switch..case
e, dependendo de seu resultado, exibir um bloco específico. Por exemplo:
import { Component } from "@angular/core";
import { NgSwitch, NgSwitchCase, NgSwitchDefault } from "@angular/common";
dd@Component({
selector: "my-app",
standalone: true,
imports: [NgSwitch, NgSwitchCase, NgSwitchDefault],
template: `<div [ngSwitch]="count">
<ng-template ngSwitchCase="1">{{count * 10}}</ng-template>
<ng-template ngSwitchCase="2">{{count * 100}}</ng-template>
<ng-template ngSwitchDefault>{{count * 1000}}</ng-template>
</div>`
})
export class AppComponent {
count = 5;
}
A diretiva ngSwitch
recebe uma expressão como valor. Neste caso, é a propriedade count
. Dentro do elemento <ng-template>
, a diretiva ngSwitchCase
compara o valor da expressão do ngSwitch
com outro valor. Se ambos forem iguais, o bloco de template correspondente será utilizado. Caso contrário, a execução passa para as próximas instruções ngSwitchCase
. Se nenhuma das instruções ngSwitchCase
for executada, a instrução ngSwitchDefault
será acionada.