Sergio Hidalgo
Apasionado por la tecnología. Ninja Developer, FullStack, Adm Servidores, Profesor de Angular, Node, Phaser, Javascript. sergiohidalgocaceres@gmail.com https://www.facebook.com/groups/607163139705114/
Directivas
Las directivas crean, eliminan o modifican el aspecto de un elemento
Directivas
De atributos
Estructurales
Modifican el aspecto de un elemento a través de CSS
Directivas de atributos
Es una directiva de atributo que modifica el aspecto de un elemento usando propiedades de CSS
ngStyle
<div>
<h2>Camisas</h2>
<span [ngStyle]="{color: precioBajo(10)}">Precio: 15 soles</span>
</div>...
precioBajo(precio: number): string {
return precio<=20 ? "red" : "black"
}
...Es una directiva de atributo que modifica el aspecto de un elemento usando reglas de CSS (clases)
ngClass
<div>
<h2>Camisas</h2>
<span
[ngClass]="{oferta: precio <= 20, normal: precio>20}">
Precio: 15 soles
</span>
</div>.oferta {
color: red
}
.normal {
color: green
}Tarea 1
Crear una lista manual de los títulos de 10 canciones y asignar, aleatoriamente (Math.random), a cada una de ellas un año de lanzamiento.
El rango de años es entre 1980 y 2010.
Usando ngStyle muestren los títulos en verde para los años de 1980 a 1990, en azul para los años de 1991 a 2000 y en rojo para el resto.
Usando ngClass muestren los títulos en letra Verdana para los años de 1980 y 2000, y en Arial para el resto.
@Directive
Es el decorador que nos permite crear una directiva
Para crear una directiva se necesita importar el decorador.
import { Directive } from "@angular/core"Este decorador necesita un selector al igual que los componentes. Es un selector de atributo.
import { Directive } from "@angular/core"
@Directive({
selector: "[appMiDirectiva]"
})
export class MiDirectiva {}Las directivas se aplican a elementos.
<h1 appMiDirectiva>
Título de la web
</h1>Las directivas usan ElementRef para referenciar al elemento sobre el cual se aplica.
import { Directive, ElementRef } from "@angular/core"
...
export class MiDirectiva {
constructor(private elementRef: ElementRef) {}
}
ElementRef tiene un objeto "nativeElement" que nos permite modificar el aspecto del elemento sobre el cual se aplica la directiva.
import { Directive, ElementRef } from "@angular/core"
...
export class MiDirectiva {
constructor(private elementRef: ElementRef) {}
ngOnInit() {
this.elementRef.nativeElement.style.backgroundColor = "yellow"
}
}
Para que una directiva exista para Angular, debe registrarse en un módulo tal cual se hace con un componente.
<!-- app.module.ts -->
...
@NgModule({
declarations: [
MiDirectiva
],
...
})Las directivas, a diferencia de los componentes, no tienen Vista (html)
Para crear una directiva se puede utilizar el generador de Angular Cli.
ng generate directive directivaResaltado
ng generate d directivaResaltado
ng g d directivaResaltadoEl generador no crea una carpeta para una directiva como lo hace con un componente.
El objeto Renderer2 es más eficiente para cambiar el aspecto que usar ElementRef para referenciar a un elemento.
import { Directive, ElementRef } from "@angular/core"
...
export class MiDirectiva {
constructor(
private elementRef: ElementRef,
private renderer: Renderer2) {}
ngOnInit() {
this.renderer.setStyle(
this.elementRef.nativeElement,
"background-color",
"yellow")
}
}
El objeto Renderer2 hace más que cambiar estilos.
Tiene, entre otros, tres métodos: createElement, createText y appendChild
import { Directive, ElementRef } from "@angular/core"
...
export class MiDirectiva {
constructor(
private elementRef: ElementRef,
private renderer: Renderer2) {}
ngOnInit() {
const li = this.renderer.createElement("li")
const texto = this.renderer.createText("Texto del LI")
this.renderer.appendChild(li, texto)
this.renderer.appendChild(this.elementRef.nativeElement, li)
}
}
Más detalles de los métodos de Renderer2 los pueden encontrar en https://angular.io/api/core/Renderer2
@HostListener
El decorador HostListener nos permite interactuar con acciones del usuario como "click", "mouseenter", "mouseleave", etc.
Para usar el decorador HostListener primero hay que importarlo.
import { HostListener } from "@angular/core"...
export class MiDirectiva {
...
@HostListener("mouseenter") mouseEntra() {
this.renderer.setStyle(
this.elementRef.nativeElement,
"background-color",
"yellow")
}
@HostListener("mouseleave") mouseSale() {
this.renderer.setStyle(
this.elementRef.nativeElement,
"background-color",
"transparent")
}
}
Tarea 2
Crear una lista desordenada (ul) con un solo elemento (li).
Con cada click que le den a la lista (ul), debe agregarse un nuevo elemento (li) con el texto "nuevo elemento".
Usen @HostListener("click") y los métodos "createElement", "createText" y "appendChild".
@HostBinding
El decorador HostBinding nos permite "escuchar" los cambios en las propiedades y ejecutar una acción.
Para usar el decorador HostBinding primero hay que importarlo.
import { HostListener, HostBinding } from "@angular/core"...
export class MiDirectiva {
@HostBinding("style.backgroundColor") colorFondo: string = "transparent"
@HostListener("mouseenter") mouseEntra() {
this.colorFondo = "yellow"
}
@HostListener("mouseleave") mouseSale() {
this.colorFondo = "transparent"
}
}
Las propiedades
Las directivas pueden tener propiedades (Inputs)
...
export class MiDirectiva {
@Input() colorPorDefecto: string = "transparent"
@Input() colorHover: string = "yellow"
@HostBinding("style.backgroundColor") colorFondo: string = "transparent"
@HostListener("mouseenter") mouseEntra() {
this.colorFondo = this.colorHover
}
@HostListener("mouseleave") mouseSale() {
this.colorFondo = this.colorPorDefecto
}
ngOnInit() {
this.colorFondo = this.colorPorDefecto
}
}
Las propiedades (Inputs) hacen que las directivas se puedan reutilizar mejor.
<!-- app.component.html -->
<div appMiDirectiva [colorPorDefecto]="'red'" [colorHover]="'grey'">
Texto
</div>Así aplicamos la directiva anterior.
Podemos modificar aún más la directiva anterior, usando el selector también como un Input.
Lo hacemos aplicando un alias al Input.
...
export class MiDirectiva {
@Input("appMiDirectiva") colorPorDefecto: string = "transparent"
@Input() colorHover: string = "yellow"
...
}
Crean o eliminan elementos en el DOM.
Se reconocen porque tienen "*" como prefijo.
Directivas estructurales
Es una directiva estructural que crea o elimina elementos según una condición.
*ngIf
<div>
<h2>Camisas</h2>
<span
*ngIf="stock > 0">
Cantidad: {{stock}}
</span>
<span
*ngIf="stock == 0">
No hay stock
</span>
</div>Es una directiva estructural que crea o elimina elementos según la longitud de una lista.
*ngFor
<div *ngFor="let alumno of alumnos">
<h3>{{alumno.nombre}}</h3>
</div>
¿Cómo se ven las directivas estructurales?
Analicemos la directiva estructural "ngIf".
<div *ngIf="sinStock">
<span>No hay stock de este producto</span>
</div>Las directivas estructurales usan plantillas a través de la etiqueta "ng-template". El código de arriba es equivalente al código siguiente:
<ng-template [ngIf]="sinStock">
<div>
<span>No hay stock de este producto</span>
</div>
</ng-template>Es una combinación de directivas de atributo con directivas estructurales. Funciona de forma similar a la instrucción "switch" de JavaScript.
ngSwitch
<div [ngSwitch]="nota">
<span *ngSwitchCase="5">Tienes que mejorar (eufemismo)</span>
<span *ngSwitchCase="14">Estás bien</span>
<span *ngSwitchCase="18">Excelente</span>
<span *ngSwitchDefault>¿De verdad?</span>
</div>
Tarea 3
Crear una directiva para una etiqueta "Select".
Esta directiva recibirá como parámetro (Input) una lista (Array) de distritos.
Los items de la lista se deben mostrar como "option" de la etiqueta "Select".
Usan "createElement", "createText", "appendChild".
Tarea 4
Crear una directiva para una etiqueta "Button" con un texto "Grabar".
Cuando se haga "click" en el "button", el botón se debe desactivar (disabled) y el texto del botón debe decir "Procesando...".
Luego de 3 segundos, el botón debe activarse y volver al mensaje original.
Usen setTimeout y ngOnChanges(cambios: SimpleChanges).
By Sergio Hidalgo
Directivas de atributos y Directivas estructurales
Apasionado por la tecnología. Ninja Developer, FullStack, Adm Servidores, Profesor de Angular, Node, Phaser, Javascript. sergiohidalgocaceres@gmail.com https://www.facebook.com/groups/607163139705114/