web:javascript:angular:ngrx
Différences
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
web:javascript:angular:ngrx [2018/04/22 02:30] – [The Store] sgariepy | web:javascript:angular:ngrx [2022/02/02 00:42] (Version actuelle) – modification externe 127.0.0.1 | ||
---|---|---|---|
Ligne 10: | Ligne 10: | ||
+ | |||
+ | |||
+ | ====== Introduction ====== | ||
+ | |||
+ | {{: | ||
+ | |||
+ | |||
+ | ====== Composition de l' | ||
+ | |||
+ | |||
+ | Dans AppModule, on utilise '' | ||
+ | |||
+ | <code javascript> | ||
+ | import { StoreModule } from ' | ||
+ | |||
+ | @NgModule({ | ||
+ | imports: [ | ||
+ | BrowserModule, | ||
+ | RouterModule.forRoot(appRoutes), | ||
+ | ... | ||
+ | StoreModule.forRoot(reducer), | ||
+ | ], | ||
+ | declarations: | ||
+ | bootstrap: [ AppComponent ] | ||
+ | }); | ||
+ | |||
+ | export class AppModule {} | ||
+ | </ | ||
+ | |||
+ | Dans un module **feature**, | ||
+ | |||
+ | <code javascript> | ||
+ | import { StoreModule } from ' | ||
+ | |||
+ | @NgModule({ | ||
+ | imports: [ | ||
+ | SharedModule, | ||
+ | RouterModule.forChild(productRoutes), | ||
+ | ... | ||
+ | StoreModule.forFeature(' | ||
+ | ], | ||
+ | declarations: | ||
+ | providers: [ ... ] | ||
+ | }); | ||
+ | |||
+ | export class ProductModule {} | ||
+ | </ | ||
====== Actions ====== | ====== Actions ====== | ||
Ligne 81: | Ligne 128: | ||
<code javascript> | <code javascript> | ||
+ | import { Component, OnInit } from ' | ||
+ | import { CompanyService } from ' | ||
+ | import { Observable } from ' | ||
+ | import { Store } from ' | ||
+ | import { Company } from ' | ||
+ | import { AppState } from ' | ||
+ | import * as companyAcitons from ' | ||
+ | @Component({ | ||
+ | selector: ' | ||
+ | templateUrl: | ||
+ | styleUrls: [' | ||
+ | }) | ||
+ | export class CompanyListComponent implements OnInit { | ||
+ | |||
+ | companies$: Observable< | ||
+ | |||
+ | constructor(private store: Store< | ||
+ | |||
+ | ngOnInit() { | ||
+ | this.loadCompanies(); | ||
+ | this.companies$ = this.store.select(state => state.companies.companies); | ||
+ | } | ||
+ | |||
+ | loadCompanies() { | ||
+ | this.store.dispatch(new companyAcitons.LoadCompaniesAction()); | ||
+ | } | ||
+ | |||
+ | deleteCompany(companyId: | ||
+ | this.store.dispatch(new companyAcitons.DeleteCompanyAction(companyId)); | ||
+ | } | ||
+ | } | ||
</ | </ | ||
+ | '' | ||
+ | <code javascript> | ||
+ | import { Company } from ' | ||
+ | export interface AppState { | ||
+ | companies: { companies: Company[] } | ||
+ | } | ||
+ | </ | ||
+ | on peut créer une interface avec '' | ||
Ligne 92: | Ligne 178: | ||
+ | Fichier '' | ||
+ | |||
+ | <code javascript> | ||
+ | import { Injectable } from ' | ||
+ | import { Actions, Effect, toPayload } from ' | ||
+ | import ' | ||
+ | |||
+ | import { CompanyService } from ' | ||
+ | import * as companyActions from ' | ||
+ | import { DeleteCompanySuccessAction } from ' | ||
+ | |||
+ | @Injectable() | ||
+ | export class CompanyEffects { | ||
+ | constructor( | ||
+ | private actions$: Actions, | ||
+ | private companyService: | ||
+ | ) { } | ||
+ | |||
+ | @Effect() loadCompanies$ = this.actions$ | ||
+ | .ofType(companyActions.LOAD_COMPANIES) | ||
+ | .switchMap(() => { | ||
+ | return this.companyService.loadCompanies() | ||
+ | .map(companies => new companyActions.LoadCompaniesSuccessAction(companies)); | ||
+ | }); | ||
+ | |||
+ | @Effect() deleteCompany$ = this.actions$ | ||
+ | .ofType(companyActions.DELETE_COMPANY) | ||
+ | .switchMap((action: | ||
+ | return this.companyService.deleteCompany(action.payload) | ||
+ | .map(company => new companyActions.DeleteCompanySuccessAction(company.id)); | ||
+ | }); | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | |||
+ | < | ||
+ | @Effect({ dispatch: false }) | ||
+ | </ | ||
+ | |||
+ | Lancer une seule requête lors de plusieurs appels d' | ||
+ | |||
+ | <code javascript> | ||
+ | @Effect() | ||
+ | request$: Observable< | ||
+ | ofType< | ||
+ | distinct( | ||
+ | () => RequestTypes.REQUEST_FETCH, | ||
+ | this.actions$.pipe( | ||
+ | ofType< | ||
+ | RequestTypes.REQUEST_SUCCESS, | ||
+ | RequestTypes.REQUEST_FAILED | ||
+ | ) | ||
+ | ) | ||
+ | ), | ||
+ | mergeMap(action => | ||
+ | this.someService.request(action.data).pipe( | ||
+ | map(data => { | ||
+ | </ | ||
+ | |||
+ | |||
+ | ====== Change detection Strategies ====== | ||
+ | |||
+ | |||
+ | <code javascript> | ||
+ | @Component({ | ||
+ | selector: ' | ||
+ | templateUrl: | ||
+ | styleUrls: [' | ||
+ | changeDetection: | ||
+ | }) | ||
+ | </ | ||
+ | |||
+ | |||
+ | ====== Dispatching Actions ====== | ||
+ | |||
+ | Le // | ||
+ | |||
+ | <code javascript> | ||
+ | constructor(private store: Store< | ||
+ | </ | ||
+ | |||
+ | Par la suite, on peut lancer des actions: | ||
+ | |||
+ | <code javascript> | ||
+ | this.store.dispatch(new ProductsFetch()); | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ====== Sélecteurs ====== | ||
+ | |||
+ | L' | ||
+ | |||
+ | <code javascript> | ||
+ | interface IRequestState { | ||
+ | pending: boolean; | ||
+ | success: boolean; | ||
+ | error: any; | ||
+ | } | ||
+ | |||
+ | export const someRequestSelector: | ||
+ | AppSelectors.appSelector(), | ||
+ | (state: any) => state && state.someRequest | ||
+ | ); | ||
+ | |||
+ | export const requestSuccess: | ||
+ | IHttpState, | ||
+ | boolean | ||
+ | > = createSelector( | ||
+ | someRequestSelector, | ||
+ | (request: IRequestState) => request && request.success | ||
+ | ); | ||
+ | </ | ||
+ | |||
+ | Le sélecteur '' | ||
+ | * [[https:// | ||
Ligne 99: | Ligne 302: | ||
* [[https:// | * [[https:// | ||
* [[https:// | * [[https:// | ||
+ | * [[https:// |
web/javascript/angular/ngrx.1524357016.txt.gz · Dernière modification : 2022/02/02 00:43 (modification externe)