Skip to content

Latest commit

 

History

History
68 lines (40 loc) · 4.38 KB

File metadata and controls

68 lines (40 loc) · 4.38 KB

Capítulo 5 Servicios

Los servicios son una parte fundamental de Angular que nos permiten compartir datos y lógica entre diferentes componentes. Los servicios son clases que encapsulan funcionalidades específicas y pueden ser inyectados en componentes o en otros servicios. La inyección se realiza con un patrón conocido como DI (Dependency Injection). La inyección de dependencias es una técnica que permite a un objeto recibir sus dependencias desde el exterior en lugar de crearlas por sí mismo.

Por ejemplo, los productos no deberían ser creados directamente en el componente de lista de productos, sino que deberían ser proporcionados por un servicio. Esto permite que el componente sea más limpio y enfocado en la presentación, mientras que el servicio maneja la lógica de negocio y la obtención de datos.

Para ello:

ng generate service products

Un componente hijo puede usar los servicios de su componente padre. Por ejemplo, el componente Favorites puede usar el servicio de productos para obtener la lista de productos.

Sanboxed Services

Un servicio puede estar asociado a un componente, de tal forma que cada vez que se cree el componente, se cree una nueva instancia del servicio. Por ejemplo,

ng generate component product-view

Este componente se encargará de mostrar cada uno de los productos de la lista de productos. Para ello se bindeara la propiedad id de l producto y se recuperarán los detalles del producto con un servicio creado al efecto. Para ello, dentro del directorio src/app/product-view, creamos el servicio product-view.service.ts.

ng generate product-view.service

De esta forma, estamos indicando que este servicio es específico para el componente ProductView. Observe que el servicio ProductViewService inyecta el servicio ProductsService para poder acceder a la lista de productos y recuperar uno concreto.

Se puede restringir la búsqueda de un proveedor de servicios con el decorador @Host.

Existen otros decoradores como @Self, @SkipSelf y @Optional que permiten controlar el comportamiento de la inyección de dependencias.

Sobrescribiendo proveedores en la jerarquía de inyectores

La sintaxis que hemos usado hasta el momento para definir proveedores de servicios se llama class provider.

providers: [ProductsService]

La sintaxis anterior es una forma abreviada de la sintaxis provide object literal:

providers: [{ provide: ProductsService, useClass: ProductsService }]

La sintaxis anterior utiliza un objeto con las siguientes propiedades:

  • provide: Este es el token utilizado para configurar el inyector. Es la clase real que los consumidores de la dependencia inyectan en sus constructores.
  • useClass: Esta es la implementación real que el inyector proporcionará a los consumidores. El nombre de la propiedad diferirá según el tipo de implementación proporcionado. El tipo puede ser una clase, un valor o una factory function. En este caso, usamos useClass porque estamos proporcionando una clase.

Por ejemplo, consideremos el componente Favorites, donde usamos el pipe slice para mostrar una lista de productos favoritos en su template. ¿Qué pasaría si necesitara obtener datos a través de una versión recortada de ProductsService y no directamente de la instancia de servicio del componente ProductList? Podríamos crear un nuevo servicio que extienda la clase ProductsService y filtre los datos usando el método nativo Array.slice. Para ello, se crea un nuevo servicio que extienda ProductsService y lo llamamos FavoritesService:

ng generate service favorites.service

Servicios condicionales

En el ejemplo de la sección anterior, utilizamos la sintaxis useClass para reemplazar la implementación de la clase ProductsService inyectada. Alternativamente, podríamos crear una función factory que decida si devolverá una instancia de la clase FavoritesService o ProductsService según una condición.

Transformando objetos en servicios de Angular

Esto se puede conseguir con la sintaxis useValue. En este ejemplo, tenemos un objeto con los settings de la aplicación que inyectamos como servicio. Para ello, usamos InjectionToken<AppSettings> que permite usar el interfaz AppSettings en la propiedad provide, que espera una clase, no una interfaz.