Artigo original: How to use and create custom directives in Angular

Escrito por: Gulfam Ansari

Após explorar o Angular por algum tempo, finalmente consegui uma explicação compreensível para as diretivas do Angular. Neste artigo, vamos entender o que são as diretivas e como utilizá-las no Angular. Também criaremos nossas próprias diretivas personalizadas. Então, o que estamos esperando? Vamos começar!

O que é uma diretiva do Angular?

As diretivas são as funções que serão executadas sempre que o compilador do Angular as encontrar. Elas aprimoram a capacidade dos elementos do HTML anexando comportamentos personalizados ao DOM.

A partir do conceito central, as diretrizes do Angular são categorizadas em três categorias.

  1. Diretivas de atributos
  2. Diretivas estruturais
  3. Componentes

Diretivas de atributos

As diretivas de atributos são responsáveis pela manipulação da aparência e do comportamento dos elementos do DOM. Sendo assim, podemos usar essas diretivas para alterar o estilo dos elementos. Essas diretivas também são usadas para ocultar ou mostrar elementos específicos de modo condicional.

O Angular oferece diversas diretivas de atributo incorporadas. Alguns exemplos são a NgStyle e a NgClass. Também podemos criar nossas próprias diretivas de atributo personalizadas para a funcionalidade desejada.

Diretivas estruturais

As diretivas estruturais são responsáveis por mudar a estrutura do DOM. Elas funcionam adicionando ou removendo os elementos do DOM, ao contrário das diretivas de atributos, que apenas alteram a aparência e o comportamento do elemento.

Você pode facilmente diferenciar as diretivas estruturais e as diretivas de atributos observando apenas a sintaxe. Quando nomeamos uma diretiva estrutural, ela sempre terá como prefixo um asterisco(*), enquanto a diretiva de atributos não contém nenhum prefixo. As três diretivas estruturais do Angular mais populares são NgIf, NgFor, e NgSwitch.

Componentes

Os componentes são diretivas com modelos (templates). Essa é a única diferença entre os componentes e os outros dois tipos de diretivas. As diretivas de atributos e as estruturais não têm modelos. Portanto, podemos dizer que o componente é uma versão mais limpa e mais fácil de usar.

Usando diretivas integradas no Angular

No Angular, existem muitas diretivas integradas disponíveis, as quais você pode usar facilmente. Nesta seção, usaremos duas diretivas integradas e que são muito simples.

A diretiva NgStyle é uma diretiva de atributo usada para alterar o estilo de qualquer elemento do DOM com base em alguma condição.

<p [ngStyle]="{'background': isBlue ? 'blue' : 'red'}">Eu sou uma diretiva de atributo</p>
No código acima, estamos adicionando um fundo azul se o valor da variável isBlue for verdadeiro.  Se o valor da variável isBlue for falso, o fundo será vermelho.
<p *ngIf="show">Eu sou uma diretiva estrutural</p>
No código acima, o parágrafo permanecerá no DOM se o valor da variável show for verdadeiro. Do contrário, ele será iniciado juntamente com o DOM.

Criando uma diretiva de atributo personalizada

Criar uma diretiva personalizada é exatamente como criar um componente do Angular. Para criar uma diretiva personalizada, precisamos substituir o decorator @Component pelo decorator @Directive.

Vamos começar criando nossa primeira diretiva de atributos personalizados. Nessa diretiva, vamos destacar o elemento do DOM selecionado, definindo a cor de fundo de um elemento.

Crie um arquivo app-highlight.directive.ts dentro da pasta src/app e adicione o código abaixo.

import {
  Directive,
  ElementRef
} from '@angular/core';
@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {
  constructor(private eleRef: ElementRef) {
    eleRef.nativeElement.style.background = 'red';
  }
}

No código acima, 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 no arquivo app.module.ts.

import ...;
import { ChangeThemeDirective } from './app-highlight.directive';
@NgModule({
declarations: [
AppComponent,
ChangeThemeDirective
],
imports: [
...
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

Usaremos nossa diretiva personalizada recém-criada. Estou adicionando a diretiva appHightlight dentro do arquivo app.component.html, mas você pode usá-la em qualquer outro lugar da sua aplicação.

<h1 appHightlight>Highlight Me !</h1>

Criando uma diretiva estrutural personalizada

Na seção anterior, criamos nossa primeira diretiva de atributo. Usaremos a mesma abordagem para criar a diretiva estrutural.

Começaremos com a criação da nossa diretriz estrutural. Nessa diretiva, vamos implementar a diretiva *appNot, que funcionará de modo exatamente oposto à diretiva *ngIf.

Crie um arquivo app-not.directive.ts dentro da pasta src/app e cole o código abaixo.

import {
  Directive,
  Input,
  TemplateRef,
  ViewContainerRef
} from '@angular/core';
@Directive({
  selector: '[appNot]'
})
export class AppNotDirective {
  constructor(
    private templateRef: TemplateRef < any > ,
    private viewContainer: ViewContainerRef) {}
  @Input() set appNot(condition: boolean) {
    if (!condition) {
      this.viewContainer.createEmbeddedView(this.templateRef);
    } else {
      this.viewContainer.clear();
    }
  }
}

Como observado no código acima, estamos importando Directive, Input, TemplateRef e ViewContainerRef do @angular/core.

A Directive fornece a mesma funcionalidade para o decorator @Directive. O decorator Input é usado para a comunicação entro os dois componentes. Ele envia dados de um componente para outro usando vinculação de propriedade.

O TemplateRef representa o modelo incorporado, que é usado para instanciar as visualizações incorporadas. Essas visualizações incorporadas são vinculadas ao modelo que deve ser renderizado.

O ViewContainerRef é um contêiner em que uma ou mais visualizações podem ser anexadas. Podemos usar a função createEmbeddedView() para anexar os modelos embutidos no contêiner.

Para que a diretiva appNot funcione, precisamos adicionar nossa diretiva ao array de declarações no arquivo app.module.ts.

import ...;
import { AppNotDirective } from './app-not.directive';
@NgModule({
declarations: [
AppComponent,
AppNotDirective
],
imports: [
...
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

Agora, é hora de usarmos nossa diretiva estrutural que acabamos de criar.

Estou adicionando a diretiva appNot no app.component.html, mas você pode usá-la em qualquer lugar do aplicativo.

<h1 *appNot="true">True</h1><h1 *appNot="false">False</h1>

A diretiva *appNot é projetada de modo a anexar o elemento modelo no DOM se o valor *appNot for false, exatamente o oposto da diretiva *ngIf.

A saída do código acima deve ser parecida com esta.

Gq-nb90cSoMpnte266GnWRQb3RuUqVESuRAe

Espero que este artigo tenha respondido à maioria de suas perguntas sobre as diretivas do Angular. Boa programação para você! :)