AngularJS: Servicios, Inyección de Dependencias y Módulos

Logo de AngularJS

En el anterior post sobre angularjs explicaba la forma en que se organiza la capa de presentación alrededor de los conceptos de Views, Controllers, ViewModels y Routes. Siguiendo con mi política de conocer los frameworks sobre los que trabajo, en este post vamos a bajar de nivel y vamos a ver qué hay por debajo de la capa de presentación.

OJO: en estos post no vas a encontrar información detallada sobre cómo trabajar con angular ni mucho código fuente, si estás buscando ese tipo de detalles, te recomiendo que eches un vistazo a la documentación oficial o sigas el tutorial. Si quieres profundizar en el tema, AngularJS: Up and Running me pareció un buen libro y tengo buenas referencias del curso de AngularJS que ofrecen Pedro Hurtado y Xavier Cerdá.

Servicios

Con los elementos que veíamos en el post anterior tenemos herramientas suficientes para construir una aplicación, pero cuando la aplicación se complica, tener toda la lógica metida entre los Controllers y los ViewModels (a.k.a. $scopes), no es una buena idea.

Los servicios son un concepto importante en angular. Igual que podemos definir Controllers, podemos definir servicios en los que agrupemos funcionalidad que luego estará disponible para ser usada en los Controllers, mejorando la claridad del código y favoreciendo la reutilización.

Hasta aquí, nada nuevo. Es un concepto manejado por todos desde hace mucho tiempo y resulta familiar. La parte que puede resultar más extraña es que en angular los servicios se utilizan también para mantener estado.

En la mayoría de arquitecturas que he utilizado los servicios suelen ser objetos stateless (sin estado), que implementan operaciones pero no mantienen el estado de la aplicación. Sin embargo, en angular los servicios son la herramienta básica para mantener el estado de la aplicación (hablo siempre de la capa cliente) y compartir información entre los Controllers.

En una aplicación web MVC típica, del estilo ASPNET MVC o Rails, la información fluye entre los Controllers a través de las peticiones http, pero en una aplicación con angular no se emplea ese concepto, sino que un Controller modifica el estado de un servicio y el siguiente Controller utiliza ese servicio para acceder al nuevo estado.

En realidad, la existencia de este tipo de objetos no es algo raro, pero catalogarlos como servicios resulta un tanto confuso cuando empiezas a trabajar con angular.

Inyección de dependencias

Hace tiempo escribí de la utilidad de la inyección de dependencias en javascript y una de las cosas que me gusta de angular es que hace un uso intensivo de ella usando un contenedor de inversión de control.

Esto quiere decir que a la hora de definir cualquier componente, ya sea un Controller, un Service o lo que sea, debemos indicar de qué otros componentes depende y angular se encargará de proporcionárselos a través de la función constructura (o de la función factoría que lo construya, que para el caso es lo mismo).

Todos los componentes registrados en angular son singleton, es decir, sólo existe una instancia de ellos en la aplicación y si hay varios componentes que dependen de un mismo objeto, todos recibirán la misma instancia del objeto. Esto es lo que permite utilizar fácilmente los servicios para almacenar estado, ya que dos Controllers que dependan de un mismo servicio estarán utilizando el mismo objeto y, por tanto, podrán compartir información a través de él.

El mayor inconveniente de usar un contenedor de inyección de dependencias en un lenguaje dinámico como javascript es que necesitamos definir explicítamente las dependencias ya que no existen un sistema de tipos que permita inferirlas automáticamente. Hace tiempo explicaba cómo funcionaba switfcore.js, un contenedor IoC para javascript, y, aunque el API es distinta, las mismas pegas que comentaba en aquel post se puede aplicar a angular.

Módulos

Con todo lo que llevamos visto hasta ahora es fácil imaginarse que una aplicación con angular puede crecer bastante y gestionar las dependencias puede complicarse.

Para solucionar esto y permitirnos organizar un poco mejor el código, angular implementa un sistema de módulos de tal forma que siempre que se define un componente, se hace (o mejor dicho, se debería hacer) dentro de un módulo. Podemos asimilar estos módulos a namespaces, y podemos establecer dependencias entre módulos para que angular sepa qué componentes utilizar en cada momento.

Resumen

En estos dos posts hemos visto ya gran parte de los conceptos fundamentales que maneja angular. Quedan todavía algunas cosas más que me gustaría destacar, como el uso de directivas y filtros para encapsular pequeños bloques de comportamiento en la capa de presentación, pero eso será tema de otro post.

7 comentarios en “AngularJS: Servicios, Inyección de Dependencias y Módulos

  1. Es cierto, Jorge, y sé que lo que mucha gente quiere es ver el código.

    Justo por eso ya aviso en el segundo párrafo de lo que vas a encontrar y pongo un par de enlaces donde puedes ver código :-)

  2. Muy buena tu explicación teórica sobre la inyección de dependencias, yo soy una de las personas que al entender la teoría se me hace más fácil codificar en la práctica, así que tus conceptos me vienen muy bien, espero que sigas publicando más cosas sobre angular, que es un mundo nuevo que quiero aprender.

  3. Sergio Castillo Saldierna dijo:

    Excelente tu explicación en lo personal agradezco que nos regales tu tiempo para compartir tus conocimientos, ademas de explicarlos muy bien en referencia al código comparto la misma idea de Luis, con tu explicación nosotros aplicación los conceptos en la practica.

    Saludos :)

  4. Bueno a diferencia de Jorge, con todo respeto, código es lo que sobra en la web. Me gusta visitar este blog porque lo encuentro rico teóricamente hablando. Cuando no se tiene dominio, ni total comprensión de como funcionan las cosas, a veces terminamos haciendo unas barbaridades a nivel de código, y me incluyo, porque es frecuente cuando uno es novato. Gracias por compartir tus conocimientos, en varias ocasiones has aclarado mis dudas. Saluditos :)

  5. Esta excelente la explicación! es bueno entender los conceptos para después picarle al código.

  6. Gracias!! Justo lo que buscaba, algo que reafirma a lo que creo que estoy entendiendo para cuando usar Services en AngularJS xD…

    Saludos!

Comentarios cerrados.