Introducción
NgRx Entity es una biblioteca que facilita la gestión de colecciones de entidades en aplicaciones Angular. Proporciona una serie de utilidades para manejar operaciones comunes como la adición, actualización y eliminación de entidades, así como la selección de entidades específicas. NgRx Entity se integra perfectamente con NgRx Store, lo que permite una gestión de estado más eficiente y estructurada.
Objetivos
- Comprender qué es NgRx Entity y por qué es útil.
- Aprender a configurar NgRx Entity en una aplicación Angular.
- Realizar operaciones CRUD (Crear, Leer, Actualizar, Eliminar) utilizando NgRx Entity.
- Seleccionar y manipular entidades de manera eficiente.
Contenido
¿Qué es NgRx Entity?
NgRx Entity es una biblioteca que proporciona una serie de utilidades para gestionar colecciones de entidades en el estado de la aplicación. Facilita la manipulación de datos y reduce la cantidad de código necesario para realizar operaciones comunes.
Ventajas de Usar NgRx Entity
- Simplificación del Código: Reduce la cantidad de código necesario para manejar colecciones de entidades.
- Eficiencia: Proporciona métodos optimizados para realizar operaciones CRUD.
- Integración: Se integra perfectamente con NgRx Store y otras bibliotecas de NgRx.
Configuración de NgRx Entity
Para comenzar a usar NgRx Entity, primero debemos instalar las dependencias necesarias:
Luego, debemos importar EntityAdapter
y EntityState
en nuestro archivo de reducer:
Definición de Entidades
Primero, definimos una interfaz para nuestra entidad. Por ejemplo, si estamos manejando una colección de User
, definimos la interfaz User
:
Luego, definimos el estado utilizando EntityState
:
Creamos un adaptador para nuestra entidad:
Inicializamos el estado utilizando el adaptador:
Operaciones CRUD con NgRx Entity
NgRx Entity proporciona métodos para realizar operaciones CRUD de manera eficiente. A continuación, se muestran ejemplos de cómo realizar estas operaciones:
Adición de Entidades
Para agregar una entidad, utilizamos el método addOne
del adaptador:
import { createReducer, on } from '@ngrx/store'; import { addUser } from './user.actions'; const userReducer = createReducer( initialState, on(addUser, (state, { user }) => { return adapter.addOne(user, state); }) );
Actualización de Entidades
Para actualizar una entidad, utilizamos el método updateOne
:
import { updateUser } from './user.actions'; const userReducer = createReducer( initialState, on(updateUser, (state, { update }) => { return adapter.updateOne(update, state); }) );
Eliminación de Entidades
Para eliminar una entidad, utilizamos el método removeOne
:
import { deleteUser } from './user.actions'; const userReducer = createReducer( initialState, on(deleteUser, (state, { id }) => { return adapter.removeOne(id, state); }) );
Selección y Manipulación de Entidades
NgRx Entity también proporciona selectores para acceder a las entidades en el estado. Podemos crear selectores utilizando el adaptador:
import { createFeatureSelector, createSelector } from '@ngrx/store'; export const selectUserState = createFeatureSelector<UserState>('users'); export const { selectIds, selectEntities, selectAll, selectTotal, } = adapter.getSelectors(selectUserState);
Ejemplo de Uso de Selectores
export const selectCurrentUserId = createSelector( selectUserState, (state: UserState) => state.selectedUserId ); export const selectCurrentUser = createSelector( selectEntities, selectCurrentUserId, (userEntities, userId) => userEntities[userId] );
Ejercicio Práctico
Ejercicio
- Objetivo: Implementar una funcionalidad CRUD completa para una entidad
Product
utilizando NgRx Entity. - Pasos:
- Definir la interfaz
Product
. - Configurar el estado y el adaptador para
Product
. - Implementar acciones y reducers para agregar, actualizar y eliminar productos.
- Crear selectores para acceder a la lista de productos y a un producto específico.
- Crear componentes para agregar, actualizar y listar productos.
- Definir la interfaz
Solución
Definición de la Entidad
Configuración del Estado y Adaptador
import { EntityState, EntityAdapter, createEntityAdapter } from '@ngrx/entity'; export interface ProductState extends EntityState<Product> { selectedProductId: string | null; } export const adapter: EntityAdapter<Product> = createEntityAdapter<Product>(); export const initialState: ProductState = adapter.getInitialState({ selectedProductId: null, });
Acciones
import { createAction, props } from '@ngrx/store'; import { Product } from './product.model'; export const addProduct = createAction( '[Product] Add Product', props<{ product: Product }>() ); export const updateProduct = createAction( '[Product] Update Product', props<{ update: Update<Product> }>() ); export const deleteProduct = createAction( '[Product] Delete Product', props<{ id: string }>() );
Reducers
import { createReducer, on } from '@ngrx/store'; import { addProduct, updateProduct, deleteProduct } from './product.actions'; const productReducer = createReducer( initialState, on(addProduct, (state, { product }) => { return adapter.addOne(product, state); }), on(updateProduct, (state, { update }) => { return adapter.updateOne(update, state); }), on(deleteProduct, (state, { id }) => { return adapter.removeOne(id, state); }) );
Selectores
import { createFeatureSelector, createSelector } from '@ngrx/store'; export const selectProductState = createFeatureSelector<ProductState>('products'); export const { selectIds, selectEntities, selectAll, selectTotal, } = adapter.getSelectors(selectProductState); export const selectCurrentProductId = createSelector( selectProductState, (state: ProductState) => state.selectedProductId ); export const selectCurrentProduct = createSelector( selectEntities, selectCurrentProductId, (productEntities, productId) => productEntities[productId] );
Conclusión
NgRx Entity simplifica la gestión de colecciones de entidades en aplicaciones Angular, proporcionando métodos optimizados para realizar operaciones CRUD y selectores para acceder a las entidades en el estado. Al integrar NgRx Entity en tu aplicación, puedes reducir significativamente la cantidad de código necesario y mejorar la eficiencia de la gestión del estado.
En el siguiente módulo, exploraremos cómo realizar pruebas en Angular, incluyendo pruebas unitarias y de componentes, para asegurar la calidad y fiabilidad de tu aplicación.
Curso de Angular
Módulo 1: Introducción a Angular
- ¿Qué es Angular?
- Configuración del Entorno de Desarrollo
- Arquitectura de Angular
- Primera Aplicación Angular
Módulo 2: Componentes de Angular
- Entendiendo los Componentes
- Creación de Componentes
- Plantillas de Componentes
- Estilos de Componentes
- Interacción entre Componentes
Módulo 3: Enlace de Datos y Directivas
- Interpolación y Enlace de Propiedades
- Enlace de Eventos
- Enlace de Datos Bidireccional
- Directivas Incorporadas
- Directivas Personalizadas
Módulo 4: Servicios e Inyección de Dependencias
- Introducción a los Servicios
- Creación y Uso de Servicios
- Inyección de Dependencias
- Inyectores Jerárquicos
Módulo 5: Enrutamiento y Navegación
Módulo 6: Formularios en Angular
- Formularios Basados en Plantillas
- Formularios Reactivos
- Validación de Formularios
- Formularios Dinámicos
Módulo 7: Cliente HTTP y Observables
- Introducción al Cliente HTTP
- Realizando Solicitudes HTTP
- Manejo de Respuestas HTTP
- Uso de Observables
- Manejo de Errores
Módulo 8: Gestión de Estado
- Introducción a la Gestión de Estado
- Uso de Servicios para la Gestión de Estado
- NgRx Store
- NgRx Effects
- NgRx Entity
Módulo 9: Pruebas en Angular
- Pruebas Unitarias
- Pruebas de Componentes
- Pruebas de Servicios
- Pruebas de Extremo a Extremo
- Simulación de Dependencias
Módulo 10: Conceptos Avanzados de Angular
- Angular Universal
- Optimización del Rendimiento
- Internacionalización (i18n)
- Pipes Personalizados
- Animaciones en Angular