Vinculando Dados em Angular
O Angular suporta um mecanismo de vinculação, permitindo que diferentes partes do template sejam vinculadas a valores específicos definidos no componente.
No Angular, existem as seguintes formas de vinculação de dados:
Vinculação de um elemento DOM ao valor do componente (unidirecional). Nas chaves duplas, é especificada uma expressão que é vinculada:
{{expressão}}
. Por exemplo:<h1>Bem-vindo, {{name}}!</h1>
Vinculação de uma propriedade de elemento DOM ao valor do componente (unidirecional). Por exemplo:
<input type="text" [value]="name" />
Vinculação de um método do componente a um evento no DOM (um evento no DOM chama o método no componente) (unidirecional). Por exemplo:
<button (click)="addItem(text, price)">Adicionar</button>
Vinculação bidirecional, onde o elemento DOM é vinculado a um valor no componente. Neste caso, mudanças em qualquer dos lados da vinculação são refletidas automaticamente no outro. Por exemplo:
<input [(ngModel)]="name" placeholder="name" />
Além disso, é possível vincular a atributos de elementos HTML, a classes CSS e a estilos de elementos HTML.
Interpolação
A primeira forma de vinculação envolve o uso de chaves duplas, onde o valor do componente é passado para o template. Por exemplo, considere o seguinte componente:
import { Component } from "@angular/core";
@Component({
selector: "my-app",
standalone: true,
template: `<p>Nome: {{ name }}</p>
<p>Idade: {{ age }}</p>`,
})
export class AppComponent {
name = "Tom";
age = 25;
}
Ao executar a aplicação, expressões como {{ name }}
serão automaticamente substituídas pelos valores correspondentes definidos no componente:
Se durante a execução da aplicação as propriedades name
e age
no componente forem alteradas, os valores na marcação HTML, vinculados a essas propriedades, também serão atualizados automaticamente.
Vinculação de Propriedades dos Elementos HTML
Podemos vincular valores a uma propriedade de um elemento HTML. Nesse caso, a propriedade é indicada entre colchetes:
import { Component } from "@angular/core";
@Component({
selector: "my-app",
standalone: true,
template: `<input type="text" [value]="name" />`,
})
export class AppComponent {
name = "Tom";
}
É importante entender que essa vinculação não está relacionada ao atributo, mas sim à propriedade do elemento no JavaScript, que representa esse elemento HTML. Por exemplo, o elemento <input />
no JavaScript é representado pela interface HTMLInputElement, que possui a propriedade value
.
No entanto, poderíamos escrever o código da seguinte maneira:
template: `<input type="text" value="{{ name }}" />`;
Nesse caso, estamos passando o valor ao atributo do elemento utilizando interpolação.
Outro exemplo:
template: `<p [textContent]="name"></p>`;
O elemento <p>
não possui um atributo textContent
, mas a interface Node, que representa esse elemento DOM, possui a propriedade textContent
, à qual podemos vincular um valor.
Vinculação a Atributos
Às vezes, é necessário vincular não a uma propriedade, mas diretamente a um atributo do elemento HTML. Embora propriedades e atributos possam se sobrepor, como no exemplo da propriedade/atributo value
, isso nem sempre acontece. Nesse caso, podemos usar a seguinte sintaxe:
[attr.nome_atributo] = "valor";
Após o prefixo attr
, é especificado o nome do atributo.
Essa vinculação geralmente é usada com atributos de elementos aria
, svg
e table
. Por exemplo, o atributo value de um campo de entrada também pode ser vinculado aos atributos:
import { Component } from "@angular/core";
@Component({
selector: "my-app",
standalone: true,
template: `<input [attr.value]="text" />`,
})
export class AppComponent {
text = "Hello Programício";
}
Aqui, o atributo value
está vinculado à variável text
.
Vinculação a Eventos
A vinculação a eventos permite associar um método do componente a um evento de um elemento:
import { Component } from "@angular/core";
@Component({
selector: "my-app",
standalone: true,
template: `<p>Quantidade de cliques: {{ count }}</p>
<button (click)="increase()">Clique</button>`,
})
export class AppComponent {
count: number = 0;
increase(): void {
this.count++;
}
}
No template, temos um botão com um evento click
. Para lidar com esse evento, o método increase()
é definido na classe AppComponent
, que incrementa a quantidade de cliques. Como resultado, ao clicar no botão, o método será acionado:
Como alternativa, a vinculação ao evento poderia ser configurada assim:
template: `<p>Quantidade de cliques: {{count}}</p>
<button on-click="increase()">Clique</button>`;
Após o prefixo on
, é especificado o nome do evento.
Também podemos passar informações sobre o evento usando o objeto $event
:
import { Component } from "@angular/core";
@Component({
selector: "my-app",
standalone: true,
template: `<p>Quantidade de cliques: {{ count }}</p>
<button (click)="increase($event)">Clique</button>`,
})
export class AppComponent {
count: number = 0;
increase($event: any): void {
this.count++;
console.log($event);
}
}
$event
é um objeto embutido através do qual o Angular passa informações sobre o evento.
Vinculação Bidirecional
A vinculação bidirecional permite que mudanças em um lado da vinculação sejam refletidas dinamicamente no outro lado. Esse tipo de vinculação é comumente usado com elementos de entrada, como campos de texto. Por exemplo:
import { Component } from "@angular/core";
import { FormsModule } from "@angular/forms";
@Component({
selector: "my-app",
standalone: true,
imports: [FormsModule], // importando FormsModule para vinculação bidirecional
template: `<p>Olá, {{ name }}</p>
<input type="text" [(ngModel)]="name" /> <br /><br />
<input type="text" [(ngModel)]="name" />`,
})
export class AppComponent {
name = "Tom";
}
Aqui, a propriedade name
da classe AppComponent
está vinculada a três elementos: um parágrafo e dois campos de texto. Os campos de texto estão vinculados à propriedade name
por meio de vinculação bidirecional, usando a sintaxe [(ngModel)]="expressão"
.
É importante notar que, para aplicar a vinculação bidirecional a campos de formulário, é necessário importar o módulo FormsModule
no componente.
Como resultado, mudanças em um dos campos de texto serão refletidas no segundo campo de texto e no parágrafo:
Vinculação a Classes CSS
A vinculação a uma classe CSS segue a seguinte forma:
[class.nome_da_classe]="true/false"
Após o prefixo class
, é especificado o nome da classe que queremos adicionar ou remover. A vinculação depende de um valor booleano. Se for true
, a classe é aplicada; se for false
, a classe não é aplicada. Por exemplo:
import { Component } from "@angular/core";
import { FormsModule } from "@angular/forms";
@Component({
selector: "my-app",
standalone: true,
imports: [FormsModule],
template: `<div [class.redbox]="isRed"></div>
<div [class.redbox]="!isRed"></div>
<input type="checkbox" [(ngModel)]="isRed" />`,
styles: [
`
div {
width: 50px;
height: 50px;
border: 1px solid #ccc;
}
.redbox {
background-color: red;
}
`,
],
})
export class AppComponent {
isRed = false;
}
Neste exemplo, a variável isRed
está vinculada à classe redbox
, que define a cor de fundo vermelha. No primeiro bloco div
, a classe é aplicada se a variável tiver o valor true: [class.redbox]="isRed"
. No segundo bloco, a classe é aplicada se a variável tiver o valor false: [class.redbox]="!isRed"
. Usando a vinculação bidirecional à variável isRed
no elemento checkbox
, podemos alterar seu valor.
Vale notar que também podemos usar a vinculação de propriedades para definir a classe:
import { Component } from "@angular/core";
@Component({
selector: "my-app",
standalone: true,
template: `<div [class]="red"></div>`,
styles: [
`
div {
width: 50px;
height: 50px;
border: 1px solid #ccc;
}
.redbox {
background-color: red;
}
`,
],
})
export class AppComponent {
red = "redbox";
}
Vinculação de Estilos
A vinculação de estilos segue a sintaxe:
[style.propriedade_de_estilo] = "expressão ? A : B";
Após o prefixo style
, o nome da propriedade de estilo é especificado. O valor é um expressão que, se retornar true
, atribui o valor A
à propriedade de estilo; se retornar false
, atribui o valor B
. Por exemplo:
import { Component } from "@angular/core";
import { FormsModule } from "@angular/forms";
@Component({
selector: "my-app",
standalone: true,
imports: [FormsModule],
template: `<div [style.backgroundColor]="isRed ? 'red' : 'green'"></div>
<div [style.background-color]="!isRed ? 'red' : 'green'"></div>
<input type="checkbox" [(ngModel)]="isRed" />`,
styles: [
`
div {
width: 50px;
height: 50px;
border: 1px solid #ccc;
}
`,
],
})
export class AppComponent {
isRed = false;
}
A expressão [style.backgroundColor]="isRed ? 'red' : 'green'"
indica que, se a variável isRed
for true
, a propriedade de estilo background-color
receberá a cor vermelha; caso contrário, receberá a cor verde. É possível usar tanto style.background-color
quanto style.backgroundColor
, substituindo o hífen pela versão em maiúsculo da letra seguinte.