Angular-Loiane-Training

Este repositorio contem exemplos documentados e descricoes dos conteudos estudados ao longo do curso de Angular da Loiane

View project on GitHub

Diretiva de estrutura (Realiza alteracoes no DOM) customizada

como visto anteriormente o angular possui diversas diretivas as quais possuem o comportamento de estruturas comuns em diversas linguagens de programacao como exemplo ngIf e ngFor, entretando nao possui uma diretiva que possua o comportamento da estrutura else, tambem presente em diversas linguagens de programacao, para exemplicar a criacao de diretivas que alteram o DOM (estrutura do template) iremos criar uma diretiva chamada ngElse. Vamos utilizar um template com ngIf e implementar ngElse como complemento.

Template com ngIf sem alteracoes.

<div *ngIf="mostrarCursos">
    Lista de cursos
</div>
<div *ngIf="!mostrarCursos">
    Nao existem cursos na lista
</div>
<button (click)="mudarMostrarCursos()">Mostar/Ocultar lista de cursos</button>

vamos analisar o exemplo acima em sua forma desestruturada, ou seja sem utilizar o sintax sugar *

<template [ngIf]="mostrarCursos">
    <div>
        Lista de cursos
    </div>
</template>

note que ngIf nao e um atributo da tag template e sim um atributo da diretiva ngIf, logo pode ser declarado apenas como o propertyBinding, pois a inteligencia do angular detecta que o atributo e o selector da diretiva possuem o mesmo nome tornando possivel a declaracao apenas da propertyBinding. Essa analise e importante pois sera utilizado o inputProperty para receber o valor da expressao passada no template para a diretiva ngElse. Para implementar a diretiva estrutural e necessario utilizar outras classes do packege angular core, sao elas TemplateRef, que ira fazer referencia a tag template (lembre que estamos analisando a forma desestruturada da diretiva), e ViewContainerRef que ira fazer referencia ao container da view. Lembrando que para receber os valores do template e da view sera por meio de injecao de dependencia.

import { Directive, Input, TemplateRef, ViewContainerRef} from '@angular/core';

// a diretiva ngElse nao existe no angular, entao vamos criar uma
@Directive({
  selector: '[ngElse]'
})
export class DiretivaDeEstruturaDirective {

  @Input() set ngElse(condition: boolean) {
    if(!condition){ // como estamos trabalhando com ngElse, queremos o caso em que a condicao e negada
      this._viewContainerRef.createEmbeddedView(this._templateRef)
    }
    else{
      this._viewContainerRef.clear()
    }

  }

  constructor(
    private _templateRef: TemplateRef<any>, 
    private _viewContainerRef: ViewContainerRef
  ) { 

  }

}

para renderizar o conteudo de acordo com a expressao iremos utilizar o metodo createEmbeddedView() resposavel por renderizar a view embutida no template, recebe como parametro a referencia do template. e para o caso else (caso a condicao seja verdadeira), entao utilizatemos o metodo clear() e ira destruir a view.

aplicando a diretiva criada no template.

<template [ngIf]="mostrarCursos">
    <div>
        Lista de cursos
    </div>
</template>

<!-- note que mostrarCursos nao possui negacao "!" em sua declaracao -->
<template [ngElse]="mostrarCursos">
    <div>
        Nao existem cursos na lista
    </div>
</template>
<button (click)="mudarMostrarCursos()">Mostar/Ocultar lista de cursos</button>

tambem pode ser utilizado o sintax sugar com a diretiva estrutural criada.

<div *ngIf="mostrarCursos">
    Lista de cursos
</div>
<div *ngElse="mostrarCursos">
    Nao existem cursos na lista
</div>
<button (click)="mudarMostrarCursos()">Mostar/Ocultar lista de cursos</button>

A diretiva ngIf pode ser consultada no repositorio oficial do Angular