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
.