Directiva estructural en Angular 🅰

Te explico qué es una directiva estructural en Angular y creamos una.

04.06.2022 a las 13:27

Directiva estructural en Angular 🅰

Directiva estructural en Angular 🅰

Empezemos por el principio.

¿Qué es una directiva en Angular?

Las directivas pueden cambiar la apariencia o el comportamiento del DOM.


Ejemplos de directivas son el *ngIf, *ngFor... seguro que te suenan


Hay distintos tipos de directivas:

  • Directivas de atributo; alteran el comportamiento o la apariencia de un elemento del DOM y son usados como atributos. ngModel, ngClass y ngStyle
  • Directivas estructurales; alteran la estructura del DOM, agregando, modificando y eliminando elementos. *ngIf, *ngFor, *ngSwitch, *ngPlural, ngTemplate y ngComponentOutlet
  • Directivas de componente; son directivas con un Template o su propio código HTML. Escribí una artículo explicando cómo hacer una directiva personalizada 👈

Ejemplo de directivas estructural personalizada

Como ya te he contado, las directivas estructurales modifican el DOM y se reconocen muy fácil porque siempre comienzan con un *.


Vamos a crear una directiva que hará lo contrario que el *ngIf. Como sabes, el *ngIf muestra el template si la condición es true:

  <ng-template *ngIf="condition">Esto se monstrará si condition es true</ng-template>
  

Vamos a crear la directiva *ifNot que mostrará el template si la condición es false

  <ng-template ifNot="condition">Esto se monstrará si condition es false</ng-template>
  

Creando nuestra directiva personalizada

Para generar nuestra directiva utilizaremos el siguiente comando del Angular CLI:

ng generate directive ifNot

O también podemos usar su forma abreviada:

ng g d ifNot

Después de ejecutar el comando anterior se nos crearán dos archivos, el de test y el ts.


El código completo de la directiva sería:

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

// Agrega el contenido de la plantilla al DOM a menos que la condición sea verdadera.
@Directive({ selector: '[ifNot]'})
export class IfNotDirective {
  private hasView = false;

  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef) { }

  @Input() set ifNot(condition: boolean) {
    if (!condition && !this.hasView) {
      this.viewContainer.createEmbeddedView(this.templateRef);
      this.hasView = true;
    } else if (condition && this.hasView) {
      this.viewContainer.clear();
      this.hasView = false;
    }
  }
}
  

Explicando el código paso por paso

  1. Importamos Input , TemplateRef y ViewContainerRef.
      import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
      
  2. Inyectamos en el constructor TemplateRef y ViewContainerRef como variables privadas.
      constructor(private templateRef: TemplateRef<any>,private viewContainer: ViewContainerRef) { }
      

    TemplateRef te ayuda a llegar al contenido de ng-template y ViewContainerRef accede al contenedor de vista.

  3. Agreguamos una variable @Input() ifNot.
      @Input() set ifNot(condition: boolean) {
        if (!condition && !this.hasView) {
          this.viewContainer.createEmbeddedView(this.templateRef);
          this.hasView = true;
        } else if (condition && this.hasView) {
          this.viewContainer.clear();
          this.hasView = false;
        }
      }
      

    Angular establece la propiedad ifNot cada vez que cambia el valor de la condición.

Usando nuestra directiva

<p *ifNot="condition">
  Este parrafo se mostrará cuando condition sea false.
</p>
  

Hasta luego 🖖

Servicios

Software

IoT

Digitalización

Aplicaciones móviles

Consultoría

fjmduran.com v0.1.2