domingo, 9 de septiembre de 2018

Angular: 10. Rutas con parámetros

Ya hemos visto cómo utilizar las rutas para viajar de una parte de la aplicación a otra. Ahora vamos a ver lo mismo pero enviando y recibiendo parámetros entre las rutas.

Utilizando la aplicación anterior, vamos a crear un nuevo componente para que al elegir un héroe de la lista de héroes, nos muestre el detalle del héroe elegido en otra página. A priori parece básicamente una navegación básica como las que hicimos en el menú, y en realidad es así. Sin embargo, aquí la gracia consiste en que tenemos que enviar a la nueva página un identificador para que ésta sepa qué héroe hemos elegido y, por tanto, qué datos cargar.

Lo primero que tenemos que hacer es crearnos un nuevo componente llamado "heroe" (así en singular, ya que el componente "heroes" en plural es el que utilizamos para mostrar la lista de héroes) que será el que cargue los datos de cada personaje cuando los enviemos:


A continuación debemos importar e incluir la ruta a nuestro componente en el fichero "app.routes.ts":


Como se puede comprobar, al incluir la ruta en el fichero hemos puesto como camino "'heroe/:id'". Esto significa que cada vez que entremos en esa ruta (cada vez que pulsemos en el botón de ver detalle de algún héroe) vamos a enviar un parámetro llamado "id", que será el identificador del héroe pulsado, para que la aplicación sepa de qué héroe debe cargar los detalles.

Ahora debemos configurar el fichero html del componente de la lista de héroes para que el botón de detalle de cada héroe:
1. Nos envíe a la pantalla de detalles.
2. Le envíe a la pantalla de detalles el identificador del Héroe cuyo botón ha sido pulsado.

Para ello, como hemos dicho antes, vamos a modificar el fichero "heroes.component.html":


Como podemos ver, hemos añadido al *ngFor de las tarjetas de los personajes una variable "i" que tendrá el valor del index del bucle, es decir, que el primer héroe será el 0, el segundo el 1, el tercero el 2, etc.
Por otra parte, hemos añadido al botón la llamada a una nueva función "verHeroe" en el evento "onclick", a la que le pasamos la variable "i" que describimos antes.

Ahora queda modificar el componente para definir la función "verHeroe" del botón, que se encargará de llamar a la ruta del detalle del héroe y de pasar el identificador:


Como se puede ver, primero hemos importado el Router de Angular (que sirve para viajar a otra ruta), y luego lo hemos inyectado en la clase "HeroesComponent" mediante su constructor. Por último, hemos creado la función "verHeroe", en la que lo único que hacemos es llamar a la ruta "heroe", pasando como parámetro la variable identificador (a la que hemos llamado "idx" aquí).

Con esto ya estarían listos tanto la llamada a la página del detalle como el envío del parámetro identificador. Ahora debemos ver cómo podemos recibir ése parámetro desde la página de destino, en éste caso el componente "heroe" en singular.

Vamos a utilizar el servicio "heroes" que ya tenemos creado para mostrar los datos de detalle del héroe. Esto significa que el servicio "heroes" será utilizado tanto por el componente "heroes" (para mostrar la lista de héroes, como tenemos hasta ahora) como por el componente "heroe" (para mostrar el detalle del héroe elegido).

Vamos a modificar, por tanto, el servicio "heroes":


Como se puede ver, hemos creado una función "getHeroe" que es muy similar a la función "getHeroes" (que utilizamos para mostear la lista de héroes) que se encuentra en la parte superior, con la diferencia de que aquí le pasamos como parámetro un id, y que aquí no devolvemos la lista completa de héroes, sino que sólo devolvemos el héroe que se encuentre en la posición "idx" de la lista de héroes.

Tras esto, modificamos el componente "heroe" ("heroe.component.ts") para que reciba el parámetro enviado desde la lista de héroes y guarde el héroe indicado en una variable:


Como podemos ver, lo primero que hemos hecho es importar el ActivatedRoute de Angular (que nos permite recibir parámetros) y el HeroesService para poder utilizar sus funciones.
Después creamos una variable "heroe" en la clase de tipo objeto. Para hacerlo más correcto, la variable debería ser de tipo "Heroe" en lugar de tipo "any" y deberíamos importar la interfaz Heroes también, pero comprobaremos que así también funciona.
Por último, hemos modificado el constructor, que es donde está todo lo importante:
1. Inyectamos el ActivatedRoute y el HeroesService.
2. Llamamos a la función "subscribe" del ActivatedRoute, dentro de la cual llamamos a la función "getHeroe" del servicio pasando el parámetro recibido, y guardando el resultado en la variable "heroe" de la clase.

Con ésto ya tendríamos cargado el héroe indicado en nuestro componente. Sólo nos queda modificar el html del componente "heroe" para que muestre los datos por la pantalla:


Y probar que funciona correctamente:




Y eso es todo.

No hay comentarios:

Publicar un comentario