viernes, 30 de noviembre de 2018

domingo, 18 de noviembre de 2018

Angular: 26. Ciclo de vida de un componente

En Angular, los componentes tienen un ciclo de vida, es decir, una serie de funciones por defecto que son llamadas en un determinado momento.

Después de crear un componente/directiva llamando a su constructor, Angular llama a los métodos de enlace del ciclo de vida en la siguiente secuencia en momentos específicos:

sábado, 17 de noviembre de 2018

Angular: 25. Rutas Hijas

Ya hemos visto cómo crear un NavBar con las distintas opciones de menú de una aplicación y el sistema de navegación de rutas de la misma. Ahora vamos a ver cómo crear rutas hijas, es decir, que dentro de una opción de menú (componente) encontremos otro menú de navegación que nos permita cargar un componente u otro.
Tenemos una aplicación con la típica barra de navegación y su sistema de rutas general que permite navegar entre opciones de menú:


Vamos a utilizar el componente "principiantes" para crear un sistema de subrutas en su interior. Tenemos, como siempre, el componente "principiantes", el componente "navbar" (barra de navegación), y el fichero de rutas general (app.routes.ts):


Primero creamos varios componentes de prueba dentro del componente "principiantes", y también un nuevo fichero de rutas "principiantes.routes.ts", también dentro del componente "principiantes":


Este nuevo fichero de rutas lo informamos de la misma forma que el fichero de rutas general, pero haciendo referencia sólo a los componentes de prueba que creamos dentro del componente "principiantes":


Ahora modificamos el fichero de rutas general de la siguiente forma:


Como se puede ver, hemos añadido la etiqueta "children" en el componente "principiantes", indicando la constante con la que nombramos el fichero de subrutas del componente "principiantes".

Ahora, en el fichero html del componente "principiantes", creamos un menú lateral con botones y un contenedor con la etiqueta "router-outlet", que será donde cargaremos los componentes hijos. Como se puede ver, se hace de la misma forma que con la navegación general:


Con esto sería todo.
Por último, modificamos el fichero CSS del componente "principiantes" para aplicar estilo a los botones del menú lateral del componente. Esto no es necesario, sólo lo incluyo para que los colores del menú coincidan con los de la barra de navegación principal, pero no afecta en nada a su funcionamiento:


Ahora levantamos la aplicación, entramos en el menú de "Principiantes", y comprobamos que el menú lateral funciona correctamente, cargando el componente correspondiente al botón que pulsemos:


Y eso es todo. Podemos crear tantos sistemas de subrutas como queramos de esta manera.

domingo, 11 de noviembre de 2018

Angular: 24. Directiva NgSwitch

Vamos a ver otra directiva, la NgSwitch.

La directiva NgSwitch funciona como muchas directivas NgIf anidadas, es decir, si queremos mostrar un elemento u otro según el valor de una variable. Eso es exactamente lo que hacíamos con el NgIf, pero en éste caso nos servirá si la variable tiene más de 2 posibles valores.

Vamos a verlo con un ejemplo.

Primero creamos un componente llamado "ngSwitch" e insertamos la etiqueta de su selector en el "app.component.html" para que aparezca en pantalla.

Después creamos en el componente una variable llamada "alerta" y la informamos con el valor "info":


Después modificamos el html del componente como sigue:


Como se puede ver, hemos creado un contenedor principal con la directiva NgSwitch apuntando a la variable "alerta" del componente.
Dentro de ese contenedor principal, hemos creado 4 contenedores con la directiva NgSwitch apuntando al valor que debe tener la variable "alerta" para que ese contenedor se muestre por la pantalla. El último de los contenedores no apunta a ningún valor, será el que se muestre si el valor de la variable "alerta" no coincide con ninguno de los anteriores.

Así, como a la variable "alerta" le dimos el valor "info", se mostrará por pantalla sólo el segundo contenedor, pero podemos modificar el valor de la variable para que se muestre otro contenedor.

Para probarlo, levantamos la aplicación:


Comprobamos que se muestra sólo el contenedor "info".

Y eso es todo.

Angular: 23. Directivas personalizadas

Vamos a crear directivas personalizadas para nuestros elementos.

No sólo podemos utilizar las directivas que Angular tiene por defecto, sino que podemos crear las nuestras. Vamos a crear una directiva llamada "resaltado". Para ello, introducimos por consola el comando: "ng g d directives/resaltado":


Como podemos comprobar, el comando crea la carpeta "directives" y dentro el fichero "resaltado.directive.ts". Además, modifica el fichero "app.module.ts" con las importaciones necesarias:



Ahora vamos a utilizar la directiva. En el fichero "app.component.html" creamos un párrafo al que le introducimos la nueva directiva (mediante el selector que aparece en la clase "appResaltado", como siempre) y le pasamos un parámetro de tipo string llamado "orange" (el color naranja):


Ahora modificamos la clase de la directiva como sigue:


Como se puede ver, hay bastantes modificaciones. Vamos a verlas una a una:

Primero añadimos 3 importaciones en la primera línea. Estas importaciones son:
ElementRef: Esta importación permite hacer referencia al elemento html al que le hemos puesto la directiva, para poder utilizarlo y manipularlo.
HostListener: Esta importación sirve para añadir y utilizar manejadores de eventos, como hacer click o pasar el ratón por encima del elemento, que es el que vamos a utilizar.
Input: Esta importación sirve para que la directiva pueda recibir parámetros desde el html, como el parámetro "orange" que le estamos pasando nosotros.

Después, dentro de la clase, añadimos la línea:
@Input("appResaltado") nuevoColor:string;
Esta línea nos permite guardar en la variable "nuevoColor", el parámetro que le pasemos a la directiva por html.

Modificamos el constructor de la clase como sigue:
constructor(private el:ElementRef) {
  el.nativeElement.style.backgroundColor = "yellow";
}
Aquí, como parámetro del constructor, estamos inyectando el elemento html al que hace referencia la directiva, guardándolo en una variable "el".
Dentro del constructor, coloreamos el fondo del elemento de amarillo.

Añadimos el manejador de eventos:
@HostListener('mouseenter') mouseEntro() {
  this.resaltar(this.nuevoColor || 'yellow');
}
Esta función se lanza cuando pasamos el ratón por encima del elemento. Dentro llama a la función "resaltar" (que veremos luego) y le pasamos la variable "nuevoColor" (el color pasado por parámetro) o el color amarillo por defecto.

Añadimos el manejador de eventos:
@HostListener('mouseleave') mouseSalio() {
  this.resaltar(null);
}
Esta función se lanza cuando sacamos el ratón del elemento. Dentro llama a la función "resaltar" pasando nulo como parámetro.

Por último añadimos la función "resaltar":
private resaltar(color:string) {
  this.el.nativeElement.style.backgroundColor = color;
}
Esta función lo único que hace es cambiar el color de fondo del elemento con el color que recibe por parámetro, quitando el color si se recibe el parámetro nulo.

En resumen, lo que hace la directiva es, poner el color de fondo del elemento a amarillo por defecto, cambiarlo a naranja cuando se pasa el ratón por encima, y dejarlo sin color cuando se saca el ratón del elemento.

Levantamos la aplicación y lo probamos.

Al entrar, el color de fondo aparece en amarillo:


Al pasar el ratón por encima, se cambia a naranja:


Y al sacar el ratón, se elimina el color:


Y eso es todo.

martes, 6 de noviembre de 2018

Angular: 22. Directiva NgClass. Simular proceso asíncrono

Vamos a utilizar la directiva NgClass para simular un proceso asíncrono, siguiendo el ejemplo de la entrada anterior.

Vamos a crear un botón que cambie de estilo cuando se hace click en él para que parezca que está cargando algún proceso.

El botón va a tener un icono de guardado y un texto. Vamos a hacer que, cuando pulsemos en el botón:

1. Cambie el icono del botón.
2. Cambie el texto del botón.
3. Se desactive el botón.

Una vez que se haya terminado de ejecutar el proceso correspondiente (nosotros sólo vamos a ejecutar un proceso que no haga nada durante 3 segundos) el botón volverá a quedar como antes de hacer click en él.

Para empezar, modificamos el TypeScript como sigue:


Como se puede ver, hemos creado una variable booleana "loading" o cargando que inicializamos a falso. Luego hemos creado una función "ejecutar" que lo único que hace es poner la variable "loading" a verdadero, esperar 3 segundos, y luego volver a cambiarla a falso.

Modificamos el html como sigue:


Como se puede ver, hemos creado un botón que llama a la función "ejecutar" y cuyo atributo "disabled" depende de la variable "loading" del TypeScript.
Dentro del botón hay un icono cuya clase (imagen, por tanto) depende de la variable "loading", mostrando una clase u otra dependiendo de si la variable es verdadera o falsa.
Por último, dentro del botón también hay dos textos, en los que hemos incluido la directiva *ngIf para que se muestren o no los textos en el botón dependiendo del valor de la variable "loading".

Con esto estaría todo. Arrancamos la aplicación y el botón se debería mostrar así:


Y cuando hacemos click en el botón se mostraría así:


Pasados 3 segundos, el botón vuelve a su aspecto original. Y eso es todo.

Angular: 21. Directiva NgClass

La directiva NgClass nos permite asignar clases CSS a elementos de forma dinámica, de tal forma que podremos cambiar el estilo CSS de los elementos en cualquier momento durante la ejecución de la aplicación.

Nos creamos un componente llamado "clases", al que le creamos dos variables: un string llamado "alerta", al que le asignamos como valor "alert-danger" (una clase de Bootstrap que cambia el color a rojo). Creamos también un objeto con una propiedad booleana "danger", a la que asignamos true por defecto:


Luego modificamos el html del componente como sigue:


Como se puede ver, hemos incluido lo siguiente, de arriba a abajo:

1. Un div de tipo alert de Bootstrap, al que le incluimos la directiva NgClass y le damos el valor de la variable "alerta" del TypeScript del componente (que por defecto lo pusimos a rojo).

2. Dos botones que al hacer clic, cambian el valor de la variable "alerta" del TypeScript del componente (cambiando con ello el estilo del elemento alerta anterior).

3. Un texto "Hola Mundo" al que le incluimos la directiva NgClass, de forma que cambia la clase CSS (el color) a rojo si la variable "danger" del objeto propiedades es verdadera, y cambia el color a azul si es falsa.

4. Un botón que cambia el valor de la variable "danger" del objeto propiedades a verdadero o falso cada vez que se hace click en él. También le hemos incluido la directiva NgClass para cambiarle las clases CSS según el valor verdadero o falso de la variable "danger".

Por último, sólo queda modificar el "app.component.html" para incluir nuestro nuevo componente:


Ahora si levantamos la aplicación, se verá de la siguiente forma:


Pulsando en los diferentes botones, cambiamos el estilo CSS de los elementos de la pantalla como hemos descrito antes:


Y eso es todo.

domingo, 4 de noviembre de 2018

Angular: 20. Cambiar estilo CSS de un elemento dinámicamente

Podemos cambiar el estilo de un elemento dinámicamente. Veamos cómo hacerlo:

Creamos un proyecto nuevo. Luego creamos un componente, que llamaremos "ngStyle".
Modificamos el TypeScript del componente simplemente añadiendo una variable "numero" de valor 10, como sigue:


Ahora modificamos el html del componente como sigue:


Como se puede ver, creamos un párrafo al que añadimos "[style.fontSize.px]="tamano"".
Con esto estamos indicando que Angular se encargará de tratar el tamaño en píxeles del contenido del párrafo, y que éste será igual a la variable "tamano" del TypeScript.

Después tenemos dos botones a los que hemos añadido una función "click" que se encargará de aumentar o disminuir el valor de la variable "tamano" en 5 cada vez que hagamos click en ellos.

Por último, añadimos la etiqueta de nuestro componente  en el "app.component.html", como sigue:


Al levantar la aplicación, se muestra como sigue:


Ahora si hacemos click en el botón de más, aumentará el tamaño de letra del párrafo, y disminuirá si pulsamos en el botón de menos.

Y eso es todo.

jueves, 1 de noviembre de 2018

Angular: 19. Pipes impuros

Un Pipe impuro funciona exactamente igual que uno "normal", solo que son llamados en cada cambio del ciclo de detección, un click, el foco, el cambio del input etc, lo que significa que los datos que se muestren por pantalla van a estar siempre actualizados, cosa que puede no pasar con un Pipe "puro".



Para convertir un Pipe normal en uno impuro, simplemente añadimos "pure: false" dentro del objeto de su anotación:

import { Pipe, PipeTransform } from '@angular/core';
import { Lista } from '../../models/lista.model';

@Pipe({
  name: 'filtroCompletado',
  pure: false
})
export class FiltroCompletadoPipe implements PipeTransform {

  transform(listas:Lista[], completada:boolean) {
    return listas.filter(lista => {
      return lista.terminada === completada;
    });
  }

}