Estruturas Condicionais e Laços em Angular
Uma das novidades introduzidas no Angular 17 foi a adição de novas construções sintáticas ao framework para o controle de templates de componentes, permitindo definir facilmente estruturas condicionais e laços. Nas versões anteriores do Angular, utilizavam-se diretivas específicas para isso. Portanto, este artigo se refere à versão Angular 17 e superiores.
If
A construção if permite criar uma estrutura condicional, similar ao que é feito em JavaScript. Por exemplo, podemos definir o seguinte componente:
import { Component } from "@angular/core";
import { FormsModule } from "@angular/forms";
@Component({
selector: "my-app",
standalone: true,
imports: [FormsModule],
template: `<div>
<input [(ngModel)]="num" type="number" />
@if(num === 5) {
<p>A variável num é igual a 5</p>
}
</div>`,
})
export class AppComponent {
num = 5;
}Aqui, no código do componente, é definida uma variável num. No template do componente, utilizando a construção:
@if(num === 5) {
<p>A variável num é igual a 5</p>
}é verificado se a variável num é igual a 5. Se a condição for verdadeira, um parágrafo com a informação correspondente é exibido.
Para demonstração, foi configurada a vinculação bidirecional da variável num ao campo de entrada, permitindo que seu valor seja alterado dinamicamente:

Utilizando as expressões @else if() é possível verificar valores adicionais. Já a expressão @else permite definir o código para o caso de as verificações anteriores em if/else if retornarem falso:
import { Component } from "@angular/core";
import { FormsModule } from "@angular/forms";
@Component({
selector: "my-app",
standalone: true,
imports: [FormsModule],
template: `<div>
<input [(ngModel)]="num" type="number" />
@if (num === 5) {
<p>A variável num é igual a 5</p>
} @else if(num === 6) {
<p>A variável num é igual a 6</p>
} @else {
<p>O valor da variável num é desconhecido</p>
}
</div>`,
})
export class AppComponent {
num = 5;
}Se dentro da construção for necessário exibir o valor de uma variável, ele deve ser envolvido por chaves duplas, como no exemplo a seguir:
import { Component } from "@angular/core";
import { FormsModule } from "@angular/forms";
@Component({
selector: "my-app",
standalone: true,
imports: [FormsModule],
template: `<div>
<input [(ngModel)]="age" min="1" type="number" />
<h2>@if(age !== null && age > 0 && age < 110) { Your age is {{ age }} } @else { age is invalid }</h2>
</div>`,
})
export class AppComponent {
age: number | null = null;
}Neste caso, se o valor de age representar uma idade válida, ele será exibido na página. Caso contrário, a mensagem "age is invalid" será mostrada.
Switch
A construção switch, assim como em JavaScript, permite comparar uma expressão com valores específicos, que são indicados usando blocos @case. Por exemplo:
import { Component } from "@angular/core";
import { FormsModule } from "@angular/forms";
@Component({
selector: "my-app",
standalone: true,
imports: [FormsModule],
template: `<input [(ngModel)]="op" />
<p>a = {{a}} b = {{b}}</p>
<p>Resultado:
@switch (op) {
@case ("+") {
{{ a + b }}
}
@case ("-") {
{{ a - b }}
}
@case ("*") {
{{ a * b }}
}
@default {
Operação desconhecida
}
}
</p>`
})
export class AppComponent {
op = "-"; // símbolo da operação
a = 10;
b = 5;
}Aqui, a construção @switch verifica o valor da variável op, que representa o símbolo de uma operação, e dependendo do seu valor, realiza uma operação aritmética com os números a e b. Os valores a serem comparados são indicados após a expressão @case. No caso de nenhum dos valores @case corresponder à expressão verificada, aplica-se a expressão @default:

Laços e a Construção for
A construção @for permite criar um laço para iterar sobre uma coleção. Por exemplo:
import { Component } from "@angular/core";
@Component({
selector: "my-app",
standalone: true,
template: `<ul>
@for (item of items; track item) {
<li>{{ item }}</li>
}
</ul>`,
})
export class AppComponent {
items = ["Tom", "Bob", "Sam"];
}Aqui, a construção for recebe um array items. Durante a iteração, cada elemento desse array é atribuído à variável item, que pode ser exibida na página dentro da lista <ul>.
Além disso, durante a iteração, é necessário usar a expressão track/trackBy. O valor da expressão track define a chave usada para associar os elementos do array às representações no DOM. Essa definição de chave permite que o Angular execute o menor número possível de operações no DOM ao adicionar, remover ou mover elementos na coleção. Neste caso, a chave utilizada é o próprio elemento (pressupondo que o array contenha apenas nomes únicos): track item.

No entanto, o array pode conter valores não únicos. Nesse caso, o Angular recomenda o uso do valor especial $index, que, dentro do laço, indica o índice do elemento no array.
@for (item of items; track $index) {
<li>{{ item }}</li>
}Além de $index, outros valores especiais podem ser usados dentro do laço:
$count: quantidade de elementos na coleção.$first: indica se o elemento atual é o primeiro na coleção.$last: indica se o elemento atual é o último na coleção.$even: indica se o índice do elemento atual é par.$odd: indica se o índice do elemento atual é ímpar.
Exemplo de uso de alguns desses valores:
@for (item of items; track $index) {
<li>Item #{{ $index }}: {{ item }} {{$last?"(último)":""}} {{$first?"(primeiro)":""}}</li>
}Se os objetos possuem uma propriedade que define sua unicidade, como um identificador, é ainda mais simples: pode-se usar essa propriedade como chave:
import { Component } from "@angular/core";
class Item {
constructor(public id: number, public name: string) {}
}
@Component({
selector: "my-app",
standalone: true,
template: `<ul>
@for (item of items; track item.id) {
<li>{{ item.name }}</li>
}
</ul>`,
})
export class AppComponent {
items = [new Item(1, "Tom"), new Item(2, "Bob"), new Item(3, "Sam")];
}Neste exemplo, a chave utilizada é o identificador (id) do objeto Item.