Diretivas em Angular
Diretivas em Angular permitem estender e construir lógica de comportamento adicional para o HTML, são elementos que são usados no HTML do angular que serão acionadas automaticamente, quando o compilador do Angular as encontra no template.
Com as diretivas, você pode adicionar lógica dinâmica, manipular eventos, controlar a visibilidade de elementos, modificar o estilo e até mesmo criar componentes totalmente personalizados. Elas são funções essenciais, ricas em recursos e de fácil uso do desenvolvedor.
Existem três tipos de diretivas: diretivas de atributo, diretivas estruturais e diretivas de componente.
Diretivas de Atributo
As diretivas de atributo alteram a aparência ou o comportamento de um elemento, componente ou outra diretiva. Elas são aplicadas como atributos HTML e manipulam o comportamento ou a aparência dos elementos.
Exemplo:
<button [disabled]="true">Clique Aqui</button>
<button [disabled]="isDisabled">Clique Aqui</button>
Neste exemplo, [disabled] é uma diretiva que desabilita o botão com base em uma condição booleana, na primeira linha ele está como true então o botão estará sempre desabilitado, já na segunda linha, isDisabled é uma variável e dependerá do valor dessa variável se o botão estará desativado ou não. Lembrando que diretivas de atributo estarão entre colchetes [] a não ser que a diretiva não receba nenhum valor.
Principais Diretivas de Atributo
| Diretiva | Resumo |
|---|---|
| ngModel | Usada principalmente para criar ligação de dados bidirecional para formulários. Permite a sincronização automática entre o modelo e a view. |
| ngClass | Permite adicionar ou remover classes de um elemento com base em expressões. |
| ngStyle | Funciona como o ngClass mas no lugar de classe, adiciona ao elemento estilo inline. |
Diretivas Estruturais
As diretivas estruturais alteram a estrutura do DOM (Document Object Model), adicionando, removendo ou manipulando elementos HTML.
Exemplo:
<div *ngIf="true">
Este elemento está sendo exibido.
</div>
Neste exemplo, *ngIf é uma diretiva estrutural que replica o comportamento de um if lógico da programação, se for verdadeiro o elemento é exibido, se for falso o Angular remove esse elemento do HTML automaticamente. Diretivas estruturais sempre possuirá um pré-fixo asterisco no inicio e não possui colchetes como as de atributo.
Principais Diretivas Estruturais
| Diretiva | Resumo |
|---|---|
| ngFor | Itera sobre uma coleção, permitindo a renderização de elementos repetidos no DOM. Útil para exibir listas de elementos dinâmicos. |
| ngIf | Adicionar ou remover elementos do DOM com base em uma condição. Útil para mostrar ou esconder elementos condicionalmente. |
| ngSwitch | Age controlando a renderização de elementos com base em diferentes condições. |
Diretivas de Componente
As diretivas de componente são diretivas que têm um template próprio. Em Angular, os componentes são diretivas com templates. Eles são declarados usando o decorator @Component.
Exemplo:
@Component({
selector: 'app-meu-componente',
templateUrl: './meu-componente.component.html'
})
export class MeuComponenteComponent {
// ...
}
Criando Diretivas
Como visto, o Angular fornece várias diretivas já prontas, mas é possível você criar novas diretivas para seu projeto. Para isto, basta chamar o decorator Directive em uma classe Typescript, e no construtor dessa classe, resgatar o ElementRef que é o objeto do elemento HTML em questão, assim, é possível aplicar um comportamento específico para esse elemento.
Para criar uma diretiva, o comando é:
ng generate directive highlight
Abaixo está um exemplo de uma diretiva que pinta o background do elemento de vermelho:
import {
Directive,
ElementRef
} from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(private eleRef: ElementRef) {
eleRef.nativeElement.style.background = 'red';
}
Aqui estamos importando a Directive e o ElementRef do core do Angular. A Directive fornece a funcionalidade do decorator @Directive, onde fornecemos seu seletor de propriedade para appHighLight para que possamos usar esse seletor em qualquer parte da aplicação. Também estamos importando o ElementRef, que é responsável por acessar o elemento do DOM.
Agora, para que a diretiva appHighlight funcione, precisamos adicionar nossa diretiva ao conjunto de declarações do módulo que fará uso, após isso, sua declaração no template HTML é da seguinte forma:
<h1 appHightlight>Highlight Me !</h1>
Não precisa do colchetes uma vez que essa diretiva não recebe nenhum dado.
Passando dados para as Diretivas criadas
Como visto nas diretivas built-in, é possível enviar um dado para as diretivas que é necessário para suas lógica, como por exemplo o ngIf que espera receber um valor verdadeiro ou falso, para fazer isso na construção de uma diretiva, basta usar o já conhecido @Input.
import {
Directive,
ElementRef
} from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
@Input() backgroundColor: string;
constructor(private eleRef: ElementRef) {
eleRef.nativeElement.style.background = backgroundColor;
}
}
Agora, quem usar essa diretiva que passará a cor do fundo.
<h1 [appHightlight]='red'>Highlight Me !</h1>
Diretivas com eventos HTML
Uma diretiva também pode lidar com eventos HTML, como click, mouseover, keypress, e isso é possível sem uso de data-binding, com o uso do decorator HostListener, que funciona parecido como o addEventListener,esse decorator irá aguardar o nome do evento e será usado em um método. vamos criar um exemplo com o appHighlight, onde agora o background irá aparecer apenas quando o mouse do usuário estive dentro do elemento, e quando tirar o mouse o background irá sumir, podemos fazer da seguinte forma:
import {
Directive,
ElementRef
} from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
@Input() backgroundColor: string;
constructor(private eleRef: ElementRef) {
}
private highlight(isHighLight) {
if (isHighLight) {
this.el.nativeElement.style.backgroundColor = backgroundColor;
}
else {
this.el.nativeElement.style.backgroundColor = '';
}
}
//@HostListener('nomeDoEvento') metodoInvado(){}
@HostListener('mouseenter') onMouseEnter() {
this.highlight(true);
}
@HostListener('mouseleave') onMouseLeave() {
this.highlight(false);
}
}