Experts in Angular

Os 7 pilares fundamentais do AngularRenderizando Templates Dinâmicos: A Tela da Nave Estelar Ganha Vida
Select Renderizando Templates Dinâmicos: A Tela da Nave Estelar Ganha Vida Renderizando Templates Dinâmicos: A Tela da Nave Estelar Ganha Vida

Renderizando Templates Dinâmicos: A Tela da Nave Estelar Ganha Vida

Com os componentes estruturados e os dados fluindo dinamicamente, chegou o momento de dar vida à tela da nossa nave estelar.
No terceiro pilar do Angular, exploraremos a arte de renderizar templates dinâmicos, transformando dados abstratos em visuais interativos e informativos.

Assim como os visores de uma nave espacial mostram dados em tempo real aos seus tripulantes, as aplicações Angular precisam exibir conteúdo dinâmico que muda conforme as interações do usuário e as atualizações dos dados.

A Tela da Nave: Um Portal para o Universo de Dados

Imagine a tela da sua nave como um portal que se abre para o vasto universo de dados que você coletou. Através da sintaxe de templates do Angular, você pode exibir esses dados de forma organizada e intuitiva, permitindo que a tripulação tome decisões estratégicas com base em informações precisas e atualizadas.

Interpolação: Projetando Dados na Tela

A interpolação, que já exploramos anteriormente, é a ferramenta fundamental para exibir dados dinâmicos no template. Ao envolver uma expressão JavaScript entre chaves duplas {{ }}, você a transforma em um feixe de luz que projeta o resultado da expressão diretamente na tela.

Por exemplo, no nosso componente NaveItem, usamos a interpolação para exibir o nome, o tipo e o status da missão da nave:

<h3>{{ nomeNave }} ({{ tipoNave }})</h3>
<p>Status da Missão: {{ statusMissao }}</p>

Quando você precisa exibir conteúdo dinâmico no seu template, Angular utiliza a sintaxe de duplas chaves {{ }} para distinguir entre conteúdo estático e dinâmico.

// nave-item.component.ts
import { Component } from '@angular/core';

@Component({
  standalone: true,
  selector: 'nave-item',
  template: `
    <p>Título da Missão: {{ tituloMissao }}</p>
  `,
})
export class NaveItemComponent {
  tituloMissao = 'Exploração de Marte';
}

Quando o Angular renderiza o componente, você verá a saída

<p>Título da Missão: Exploração de Marte</p>

Esta sintaxe declara uma interpolação entre a propriedade de dados dinâmica dentro do HTML. Como resultado, sempre que os dados mudam, o Angular atualizará automaticamente o DOM refletindo o novo valor da propriedade.

Propriedades Dinâmicas: A Tela que se Adapta à Missão

As propriedades dinâmicas são como painéis de controle que se ajustam às necessidades da missão. Ao vincular uma propriedade de um elemento HTML a uma expressão Angular, você permite que o valor da propriedade seja atualizado automaticamente sempre que a expressão mudar.

Por exemplo, para exibir a porcentagem de energia do escudo da nave em uma barra de progresso, podemos usar a seguinte sintaxe:

<div class="escudo-energia">
  <div class="barra-progresso" [style.width.%]="escudoEnergia"></div>
</div>

Nesse caso, a propriedade width do elemento div.barra-progresso está vinculada à expressão escudoEnergia. Se o valor de escudoEnergia for 85, a barra de progresso terá uma largura de 85%. Se o valor de escudoEnergia mudar, a largura da barra será atualizada automaticamente.

Quando você precisa definir dinamicamente o valor de propriedades padrão do DOM em um elemento HTML, a propriedade é envolvida entre colchetes para informar ao Angular que o valor declarado deve ser interpretado como uma expressão semelhante a JavaScript (com algumas melhorias do Angular) em vez de uma string simples.

Um exemplo comum de atualização dinâmica de propriedades no seu HTML é determinar se o botão de envio de um formulário deve estar desabilitado com base na validade do formulário.

Envolva a propriedade desejada entre colchetes para informar ao Angular que o valor atribuído é dinâmico (ou seja, não é uma string estática).

Por exemplo, para desabilitar o botão “Iniciar Missão” quando a missão já estiver em andamento, podemos usar o seguinte código:

<button [disabled]="statusMissao === 'Em andamento'">Iniciar Missão</button>

Nesse caso, o atributo disabled do botão está vinculado à expressão statusMissao === 'Em andamento'. Se o valor de statusMissao for “Em andamento”, a expressão será verdadeira e o botão será desabilitado. Se o valor de statusMissao mudar para outro valor, o botão será habilitado novamente.

Atributos Dinâmicos: Personalizando a Nave em Tempo Real

Os atributos dinâmicos permitem que você personalize a aparência e o comportamento dos elementos HTML de acordo com o estado da sua aplicação. Ao vincular um atributo a uma expressão Angular, você permite que o valor do atributo seja atualizado dinamicamente.

Quando você precisa vincular dinamicamente atributos HTML personalizados (por exemplo, aria-, data-, etc.), você pode ficar tentado a envolver os atributos personalizados com os mesmos colchetes.

// app-banner.component.ts
import { Component } from '@angular/core';

@Component({
  standalone: true,
  template: `
    <button [data-test-id]="testId">Primary CTA</button>
  `,
})
export class AppBannerComponent {
  testId = 'main-cta';
}

Infelizmente, isso não funcionará porque atributos HTML personalizados não são propriedades padrão do DOM. Para que isso funcione como pretendido, precisamos prefixar o atributo HTML

Exemplo Corrigido

// app-banner.component.ts
import { Component } from '@angular/core';

@Component({
  standalone: true,
  template: `
    <button [attr.data-test-id]="testId">Primary CTA</button>
  `,
})
export class AppBannerComponent {
  testId = 'main-cta';
}

Neste exemplo, ao usar attr., garantimos que o Angular entende que estamos nos referindo a um atributo HTML personalizado e não a uma propriedade padrão do DOM.

Aperfeiçoando o Componente NaveItem

Vamos aprimorar nosso componente NaveItem para desabilitar o botão “Iniciar Missão” quando a missão já estiver em andamento. Adicionaremos também uma barra de progresso para o nível do escudo de energia.

// nave-item.component.ts
import { Component } from '@angular/core';

@Component({
  standalone: true,
  selector: 'nave-item',
  templateUrl: './nave-item.component.html',
  styleUrls: ['./nave-item.component.css']
})
export class NaveItemComponent {
  nomeNave: string = 'USS Enterprise';
  tipoNave: string = 'Nave Estelar';
  statusMissao: string = 'Em preparação';
  tripulacao: number = 430;
  escudoEnergia: number = 85;

  iniciarMissao() {
    if (this.statusMissao !== 'Em andamento') {
      this.statusMissao = 'Em andamento';
    }
  }
}
Template HTML
<!-- nave-item.component.html -->
<div class="nave-item">
  <h3>{{ nomeNave }} ({{ tipoNave }})</h3>
  <p>Status da Missão: {{ statusMissao }}</p>
  <button [disabled]="statusMissao === 'Em andamento'" (click)="iniciarMissao()">Iniciar Missão</button>
  <div class="escudo-energia">
    <div class="barra-progresso" [style.width.%]="escudoEnergia"></div>
  </div>
</div>

Desvendando a Diferença entre Atributos e Propriedades

Em nossa jornada pelo universo Angular, é importante esclarecer a diferença entre atributos e propriedades, dois conceitos fundamentais para a criação de interfaces dinâmicas. Embora pareçam semelhantes à primeira vista, eles desempenham papéis distintos na estrutura da sua nave estelar.

Atributos: A Identidade da Nave Estelar

Imagine os atributos como a placa de identificação da sua nave estelar, contendo informações como o nome, o modelo e o número de registro. No HTML, os atributos são pares de chave-valor que fornecem informações adicionais sobre os elementos, como classes, IDs, estilos e outros dados relevantes.

Por exemplo, no elemento <button class="botao-primario" id="botao-iniciar-missao">, class e id são atributos que definem a classe e o identificador do botão, respectivamente.

Propriedades: O Estado da Nave Estelar

As propriedades, por sua vez, representam o estado atual da sua nave estelar, como a velocidade, a temperatura e o nível de energia. No DOM (Document Object Model), que é a representação em árvore do seu documento HTML, cada elemento possui um conjunto de propriedades que podem ser acessadas e manipuladas através de JavaScript.

Por exemplo, o elemento <button> possui propriedades como disabled (indica se o botão está desabilitado), textContent (o texto exibido no botão) e style (os estilos CSS aplicados ao botão).

A Ponte entre Atributos e Propriedades

Em muitos casos, existe uma relação direta entre atributos e propriedades. Por exemplo, o atributo class de um elemento HTML corresponde à propriedade className no DOM. No entanto, nem sempre essa relação é tão simples.

Alguns atributos, como disabled, não possuem uma propriedade correspondente no DOM. Nesses casos, a presença do atributo é suficiente para definir o estado da propriedade. Por exemplo, se um botão tiver o atributo disabled, a propriedade disabled do botão no DOM será automaticamente definida como true.

Propriedades Dinâmicas vs. Atributos Dinâmicos

No Angular, utilizamos o property binding (colchetes []) para manipular propriedades dinamicamente e o attribute binding (colchetes [] com o prefixo attr.) para manipular atributos dinâmicos.

  • Property Binding: Usado para propriedades que possuem uma representação direta no DOM, como className, textContent, value, etc.
  • Attribute Binding: Usado para atributos que não possuem uma propriedade correspondente no DOM, como data-test-id, aria-label, etc.

Exemplo Comparativo: NaveItem com Propriedade e Atributo Dinâmicos

@Component({
  // ... (standalone, selector, templateUrl, styleUrls)
  template: `
    <div class="nave-item" [attr.data-nave-id]="idNave">
      <h3 [class.missao-ativa]="statusMissao === 'Em andamento'">{{ nomeNave }} ({{ tipoNave }})</h3> 
      <p>Status da Missão: {{ statusMissao }}</p>
      <button [disabled]="statusMissao === 'Em andamento'" (click)="iniciarMissao()">Iniciar Missão</button>
      <div class="escudo-energia">
        <div class="barra-progresso" [style.width.%]="escudoEnergia"></div>
      </div>
    </div>
  `,
  styles: `
    /* ... (estilos) */
    .missao-ativa {
      color: green; /* Estilo para quando a missão está ativa */
    }
  `
})
export class NaveItemComponent {
  // ... (outras propriedades)
  @Input() idNave: number = 1;
}

Neste exemplo, usamos o property binding para vincular a propriedade class do elemento <h3> à expressão statusMissao === 'Em andamento'. Se a missão estiver em andamento, a classe “missao-ativa” será adicionada ao elemento, alterando sua cor para verde. Já o atributo data-nave-id é manipulado através do attribute binding.

Atributos

  • Atributos são parte do HTML.
  • São valores que você define no HTML e que permanecem constantes, a menos que sejam modificados explicitamente.
  • São sempre strings.
  • Exemplos: id, class, data-*, aria-*.

Propriedades

  • Propriedades são parte do DOM (Document Object Model).
  • São valores que você define e manipula através do JavaScript.
  • Podem ser de diferentes tipos (não apenas strings), como booleanos, números, objetos, etc.
  • Exemplos: disabled, checked, value, style.

A renderização de templates dinâmicos é uma das características mais poderosas do Angular, permitindo que suas aplicações sejam altamente interativas e responsivas às mudanças de dados. Seja através da interpolação de dados, controle de propriedades dinâmicas ou atributos dinâmicos, você pode criar interfaces de usuário ricas e dinâmicas.

Próxima Parada: Condicionais e Loops

🚀 Prepare-se para a próxima etapa da nossa jornada pelo universo Angular! No próximo artigo, exploraremos o poder das condicionais e loops, que nos permitem criar interfaces inteligentes e personalizadas, capazes de se adaptar a diferentes situações e dados.

Compartilhe sua Opinião e Explore o Código-Fonte!

💬 Gostou de desvendar os segredos da renderização dinâmica de templates? Deixe seus comentários e sugestões para nos ajudar a aprimorar esta série de artigos.

👨‍💻 Quer ver o código-fonte completo e contribuir para a construção da nossa frota estelar? Visite nosso repositório no GitHub.

Sua participação é fundamental para fortalecermos a comunidade de desenvolvedores Angular e explorarmos juntos as fronteiras da criação web!

Comments are closed.