NgRx Store és una llibreria per a Angular que proporciona un patró de gestió d'estat inspirat en Redux. Utilitza un únic estat immutable i accions per modificar-lo, facilitant la gestió de l'estat de l'aplicació de manera previsible i escalable.
Objectius del Mòdul
- Comprendre els conceptes bàsics de NgRx Store.
- Aprendre a configurar NgRx Store en una aplicació Angular.
- Crear accions, reducers i selectors.
- Integrar NgRx Store amb components Angular.
Conceptes Clau
Estat Centralitzat
NgRx Store utilitza un únic estat centralitzat per a tota l'aplicació, el qual és immutable. Això significa que qualsevol canvi en l'estat crea una nova còpia de l'estat en lloc de modificar l'existent.
Accions
Les accions són objectes que descriuen un canvi en l'estat. Cada acció té un tipus i, opcionalment, un payload (dades addicionals).
Reducers
Els reducers són funcions pures que prenen l'estat actual i una acció, i retornen un nou estat. Són responsables de gestionar com l'estat canvia en resposta a les accions.
Selectors
Els selectors són funcions que permeten accedir a parts específiques de l'estat de manera eficient.
Configuració de NgRx Store
Instal·lació
Per començar a utilitzar NgRx Store, primer cal instal·lar les dependències necessàries:
Configuració Bàsica
-
Definir l'Estat Inicial:
export interface AppState { counter: number; } export const initialState: AppState = { counter: 0, };
-
Crear Accions:
import { createAction } from '@ngrx/store'; export const increment = createAction('[Counter] Increment'); export const decrement = createAction('[Counter] Decrement'); export const reset = createAction('[Counter] Reset');
-
Crear Reducer:
import { createReducer, on } from '@ngrx/store'; import { increment, decrement, reset } from './counter.actions'; import { AppState, initialState } from './app.state'; const _counterReducer = createReducer( initialState, on(increment, (state) => ({ ...state, counter: state.counter + 1 })), on(decrement, (state) => ({ ...state, counter: state.counter - 1 })), on(reset, (state) => ({ ...state, counter: 0 })) ); export function counterReducer(state: AppState | undefined, action: Action) { return _counterReducer(state, action); }
-
Registrar el Reducer en el Mòdul:
import { NgModule } from '@angular/core'; import { StoreModule } from '@ngrx/store'; import { counterReducer } from './counter.reducer'; @NgModule({ imports: [ StoreModule.forRoot({ counter: counterReducer }), ], }) export class AppModule {}
-
Utilitzar Selectors:
import { createSelector, createFeatureSelector } from '@ngrx/store'; import { AppState } from './app.state'; export const selectCounterState = createFeatureSelector<AppState>('counter'); export const selectCounter = createSelector( selectCounterState, (state: AppState) => state.counter );
-
Integrar amb Components:
import { Component } from '@angular/core'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; import { AppState } from './app.state'; import { increment, decrement, reset } from './counter.actions'; import { selectCounter } from './counter.selectors'; @Component({ selector: 'app-counter', template: ` <div> <h1>{{ counter$ | async }}</h1> <button (click)="increment()">Increment</button> <button (click)="decrement()">Decrement</button> <button (click)="reset()">Reset</button> </div> `, }) export class CounterComponent { counter$: Observable<number>; constructor(private store: Store<AppState>) { this.counter$ = this.store.select(selectCounter); } increment() { this.store.dispatch(increment()); } decrement() { this.store.dispatch(decrement()); } reset() { this.store.dispatch(reset()); } }
Exercicis Pràctics
Exercici 1: Crear una Acció Personalitzada
- Crea una nova acció
set
que permeti establir el valor del comptador a un valor específic. - Modifica el reducer per gestionar aquesta nova acció.
- Actualitza el component per utilitzar aquesta acció.
Solució:
-
Crear Acció:
export const set = createAction('[Counter] Set', props<{ value: number }>());
-
Modificar Reducer:
const _counterReducer = createReducer( initialState, on(increment, (state) => ({ ...state, counter: state.counter + 1 })), on(decrement, (state) => ({ ...state, counter: state.counter - 1 })), on(reset, (state) => ({ ...state, counter: 0 })), on(set, (state, { value }) => ({ ...state, counter: value })) );
-
Actualitzar Component:
@Component({ selector: 'app-counter', template: ` <div> <h1>{{ counter$ | async }}</h1> <button (click)="increment()">Increment</button> <button (click)="decrement()">Decrement</button> <button (click)="reset()">Reset</button> <button (click)="setCounter(5)">Set to 5</button> </div> `, }) export class CounterComponent { counter$: Observable<number>; constructor(private store: Store<AppState>) { this.counter$ = this.store.select(selectCounter); } increment() { this.store.dispatch(increment()); } decrement() { this.store.dispatch(decrement()); } reset() { this.store.dispatch(reset()); } setCounter(value: number) { this.store.dispatch(set({ value })); } }
Resum
En aquest mòdul, hem après els conceptes bàsics de NgRx Store, com configurar-lo en una aplicació Angular, i com crear accions, reducers i selectors. També hem vist com integrar NgRx Store amb components Angular per gestionar l'estat de l'aplicació de manera eficient. Els exercicis pràctics proporcionats ajuden a reforçar aquests conceptes i a aplicar-los en situacions reals.
Curs d'Angular
Mòdul 1: Introducció a Angular
- Què és Angular?
- Configuració de l'entorn de desenvolupament
- Arquitectura d'Angular
- Primera aplicació Angular
Mòdul 2: Components d'Angular
- Comprendre els components
- Crear components
- Plantilles de components
- Estils de components
- Interacció de components
Mòdul 3: Enllaç de dades i directives
- Interpolació i enllaç de propietats
- Enllaç d'esdeveniments
- Enllaç de dades bidireccional
- Directives integrades
- Directives personalitzades
Mòdul 4: Serveis i injecció de dependències
Mòdul 5: Enrutament i navegació
Mòdul 6: Formularis a Angular
Mòdul 7: Client HTTP i observables
- Introducció al client HTTP
- Fer sol·licituds HTTP
- Gestionar respostes HTTP
- Utilitzar observables
- Gestió d'errors
Mòdul 8: Gestió d'estat
- Introducció a la gestió d'estat
- Utilitzar serveis per a la gestió d'estat
- NgRx Store
- NgRx Effects
- NgRx Entity
Mòdul 9: Proves a Angular
- Proves unitàries
- Proves de components
- Proves de serveis
- Proves de cap a cap
- Simulació de dependències
Mòdul 10: Conceptes avançats d'Angular
- Angular Universal
- Optimització del rendiment
- Internacionalització (i18n)
- Tubs personalitzats
- Animacions d'Angular