Introducció a NgRx Effects
NgRx Effects és una biblioteca que permet gestionar efectes secundaris en una aplicació Angular utilitzant el patró Redux. Els efectes secundaris són operacions que no modifiquen l'estat directament, com ara sol·licituds HTTP, interaccions amb serveis externs, o qualsevol altra operació asíncrona. NgRx Effects ajuda a mantenir el codi net i organitzat, separant la lògica d'efectes secundaris de la lògica de gestió d'estat.
Objectius d'aquest tema:
- Comprendre què són els efectes en NgRx.
- Aprendre a crear i gestionar efectes amb NgRx Effects.
- Veure exemples pràctics d'ús d'efectes per gestionar sol·licituds HTTP.
Conceptes Clau
Què són els efectes?
Els efectes són classes que contenen lògica per gestionar operacions asíncrones i altres efectes secundaris. Utilitzen observables per escoltar accions i emetre noves accions en resposta.
Per què utilitzar NgRx Effects?
- Separació de preocupacions: Manté la lògica d'efectes secundaris fora dels reducers.
- Testabilitat: Els efectes es poden provar fàcilment de manera aïllada.
- Escalabilitat: Facilita la gestió de lògica complexa i asíncrona en aplicacions grans.
Configuració de NgRx Effects
Instal·lació
Per començar a utilitzar NgRx Effects, primer cal instal·lar el paquet @ngrx/effects
:
Configuració bàsica
Després d'instal·lar el paquet, cal configurar NgRx Effects en el mòdul principal de l'aplicació:
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { StoreModule } from '@ngrx/store'; import { EffectsModule } from '@ngrx/effects'; import { AppComponent } from './app.component'; import { reducers } from './store/reducers'; import { MyEffects } from './store/effects/my-effects'; @NgModule({ declarations: [AppComponent], imports: [ BrowserModule, StoreModule.forRoot(reducers), EffectsModule.forRoot([MyEffects]) ], providers: [], bootstrap: [AppComponent] }) export class AppModule {}
Creació d'Efectes
Exemple pràctic: Sol·licitud HTTP
Suposem que volem fer una sol·licitud HTTP per obtenir una llista d'usuaris. Primer, definim les accions necessàries:
import { createAction, props } from '@ngrx/store'; export const loadUsers = createAction('[User] Load Users'); export const loadUsersSuccess = createAction( '[User] Load Users Success', props<{ users: User[] }>() ); export const loadUsersFailure = createAction( '[User] Load Users Failure', props<{ error: any }>() );
Definició de l'efecte
Ara, creem una classe d'efectes per gestionar la sol·licitud HTTP:
import { Injectable } from '@angular/core'; import { Actions, createEffect, ofType } from '@ngrx/effects'; import { of } from 'rxjs'; import { catchError, map, mergeMap } from 'rxjs/operators'; import { UserService } from '../services/user.service'; import * as UserActions from '../actions/user.actions'; @Injectable() export class UserEffects { loadUsers$ = createEffect(() => this.actions$.pipe( ofType(UserActions.loadUsers), mergeMap(() => this.userService.getUsers().pipe( map(users => UserActions.loadUsersSuccess({ users })), catchError(error => of(UserActions.loadUsersFailure({ error }))) ) ) ) ); constructor( private actions$: Actions, private userService: UserService ) {} }
Explicació del codi
- Actions: És un flux d'accions que NgRx proporciona per permetre escoltar accions específiques.
- createEffect: Crea un efecte que escolta accions i emet noves accions en resposta.
- ofType: Filtra les accions per tipus.
- mergeMap: Permet gestionar operacions asíncrones i emetre múltiples accions.
- catchError: Gestiona errors i emet una acció de fallada.
Exercici Pràctic
Objectiu
Crear un efecte que faci una sol·licitud HTTP per obtenir dades de productes i gestioni les accions de càrrega, èxit i fallada.
Passos
-
Definir les accions:
import { createAction, props } from '@ngrx/store'; export const loadProducts = createAction('[Product] Load Products'); export const loadProductsSuccess = createAction( '[Product] Load Products Success', props<{ products: Product[] }>() ); export const loadProductsFailure = createAction( '[Product] Load Products Failure', props<{ error: any }>() );
-
Crear el servei:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { Product } from '../models/product.model'; @Injectable({ providedIn: 'root' }) export class ProductService { private apiUrl = 'https://api.example.com/products'; constructor(private http: HttpClient) {} getProducts(): Observable<Product[]> { return this.http.get<Product[]>(this.apiUrl); } }
-
Definir l'efecte:
import { Injectable } from '@angular/core'; import { Actions, createEffect, ofType } from '@ngrx/effects'; import { of } from 'rxjs'; import { catchError, map, mergeMap } from 'rxjs/operators'; import { ProductService } from '../services/product.service'; import * as ProductActions from '../actions/product.actions'; @Injectable() export class ProductEffects { loadProducts$ = createEffect(() => this.actions$.pipe( ofType(ProductActions.loadProducts), mergeMap(() => this.productService.getProducts().pipe( map(products => ProductActions.loadProductsSuccess({ products })), catchError(error => of(ProductActions.loadProductsFailure({ error }))) ) ) ) ); constructor( private actions$: Actions, private productService: ProductService ) {} }
-
Configurar l'efecte en el mòdul:
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { StoreModule } from '@ngrx/store'; import { EffectsModule } from '@ngrx/effects'; import { AppComponent } from './app.component'; import { reducers } from './store/reducers'; import { ProductEffects } from './store/effects/product-effects'; @NgModule({ declarations: [AppComponent], imports: [ BrowserModule, StoreModule.forRoot(reducers), EffectsModule.forRoot([ProductEffects]) ], providers: [], bootstrap: [AppComponent] }) export class AppModule {}
Resum
En aquest tema, hem après què són els efectes en NgRx i com utilitzar NgRx Effects per gestionar operacions asíncrones i altres efectes secundaris en una aplicació Angular. Hem vist com crear i configurar efectes, així com un exemple pràctic de sol·licitud HTTP. Els efectes ajuden a mantenir el codi net, organitzat i fàcil de provar, millorant la mantenibilitat i escalabilitat de l'aplicació.
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