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:

npm install @ngrx/entity

Luego, debemos importar EntityAdapter y EntityState en nuestro archivo de reducer:

import { EntityState, EntityAdapter, createEntityAdapter } from '@ngrx/entity';

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:

export interface User {
  id: string;
  name: string;
  email: string;
}

Luego, definimos el estado utilizando EntityState:

export interface UserState extends EntityState<User> {
  selectedUserId: string | null;
}

Creamos un adaptador para nuestra entidad:

export const adapter: EntityAdapter<User> = createEntityAdapter<User>();

Inicializamos el estado utilizando el adaptador:

export const initialState: UserState = adapter.getInitialState({
  selectedUserId: null,
});

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

  1. Objetivo: Implementar una funcionalidad CRUD completa para una entidad Product utilizando NgRx Entity.
  2. 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.

Solución

Definición de la Entidad

export interface Product {
  id: string;
  name: string;
  price: number;
}

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

Módulo 2: Componentes de Angular

Módulo 3: Enlace de Datos y Directivas

Módulo 4: Servicios e Inyección de Dependencias

Módulo 5: Enrutamiento y Navegación

Módulo 6: Formularios en Angular

Módulo 7: Cliente HTTP y Observables

Módulo 8: Gestión de Estado

Módulo 9: Pruebas en Angular

Módulo 10: Conceptos Avanzados de Angular

Módulo 11: Despliegue y Mejores Prácticas

© Copyright 2024. Todos los derechos reservados