3 formas de comunicarse entre componentes Angular

Este artículo esta basado en Angular 2+. En el momento de escribirlo, la última versión era Angular 4.
Está pensado para principiantes – si eres un desarrollador de Angular experimentado, probablemente ya conoces estas técnicas.

Actualización: el título de este artículo puede llevar a confusión, porque en realidad no pretendemos que los componentes se comuniquen directamente. Nuestros componentes deberían estar encapsulados y aislados. He elegido este título porque pienso que los desarrolladores que tengan este problema realizarán una búsqueda con estas palabras.

¿Cómo comunicarse entre componentes? Este es el tema con el que he visto a muchos desarrolladores de Angular tener problemas. Mostraremos los tres enfoques más comunes, con ejemplos que encajan en diferentes casos de uso.
Hay otro modo vía ‘redux’ que posiblemente veamos en un nuevo artículo.



Imagina un caso de uso en el que tenemos una barra lateral en la aplicación. La barra puede estar abierta o cerrada. Tenemos el componente side-bar y otro componente (o varios) que puede abrirla/cerrarla o preguntar por su estado.

Describiremos tres maneras de implementar este comportamiento

  1. Pasar la referencia de un componente a otro
  2. Comunicación a través de un componente padre
  3. Comunicación a través de un servicio

Cada uno de estos ejemplos tiene una aplicación de demostración con su código en StackBlitz y repositorio github.


1. Pasando la referencia de un componente a otro

Esta solución debería usarse cuando los componentes tienen dependencia entre ellos. Por ejemplo, un desplegable y el botón para desplegar. Normalmente no puede existir el uno sin el otro.

Demo
Repositorio github

Crearemos un componente para abrir/cerrar la barra lateral (side-bar-toggle) que tendrá la barra lateral como un input, y al hacer clic en el botón abriremos o cerrarmos el componente side-bar.
Este es el código:

Los imports se han omitido en el código TypeScript.


Comunicación a través de un componente padre

Puede utilizarse cuando es sencillo controlar el estado compartido entre componentes a través del componente padre y no queremos crear un nuevo servicio por culpa de una sola variable.

Demo
Repositorio Github

La implementación de este enfoque es casi igual que la anterior, aunque el side-bar-toggle no recibe el componente side-bar. En su lugar, el componente padre tiene la propiedad sideBarIsOpened (barraLateralAbierta), que se pasa al componente side-bar.

Los imports se han omitido en el código TypeScript.


Comunicación a través de un servicio

Finalmente, esta opción debería usarse cuando tenemos un componente que o bien es controlado o bien su estado es consultado desde múltiples instancias.

Demo
Repositorio Github


Ahora tenemos varios lugares en la aplicación que necesitan acceder a nuestro componente side-bar. Vamos a ver como lo hacemos:
Crearemos un servicio side-bar.service.ts, de forma que tendremos:

  • side-bar.service.ts
  • side-bar.component.ts
  • side-bar.component.html

El servicio de la barra lateral tendrá un método ‘toggle’ (conmutar) y un evento ‘change’ (cambio) de modo que a cualquier componente que inyecte este servicio se le podrá notificar que el panel se ha abierto o puede abrirse/cerrarse.
En este ejemplo ni el componente side-bar ni side-bar-toggle tiene parámetros de input, porque se comunican a través de un servicio.
Ahora, el código:

Los imports se han omitido en el código TypeScript.

Si tienes otro modo de hacer esto, o tienes problemas con alguno de los ejemplos, puedes indicármelo en los comentarios.
No olvides seguirme en Medium para más artículos de JavaScript/Angular.

Puedes contactar conmigo en Instagram y seguirme en Twitter. Seguiré publicando los artículos más interesantes del mundo JavaScript.
Otros artículos que podrían interesarte (en inglés):
Volviendo a las raíces JavaScript: valor VS referencia

Nota: puedes encontrar el artículo original en https://medium.com/dailyjs/3-ways-to-communicate-between-angular-components-a1e3f3304ecb

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *