如何编写第一个 ngrx Effect 类
官網
要將副作用與您的組件隔離,您必須創建一個 Effects 類來偵聽事件并執行任務。
Effect 是具有不同部分的可注入服務類:
- 一個可注入的 Actions 服務,它提供了在 reduce 最新狀態后調度的所有操作的可觀察流。
如下圖所示:
-
使用 createEffect 函數將元數據附加到可觀察流。 元數據用于注冊訂閱存儲的流。從 effect 流返回的任何操作都會被分派回 Store。
-
使用可管道化的 ofType 運算符過濾操作。 ofType 運算符將一種或多種操作類型作為參數來過濾要執行的操作。
如下圖所示:
-
effects 訂閱了 Store observable.
-
服務被注入到效果中以與外部 API 交互并處理流。
看一個實際的 effects 實現例子:
import { Injectable } from '@angular/core'; import { Actions, createEffect, ofType } from '@ngrx/effects'; import { EMPTY } from 'rxjs'; import { map, mergeMap, catchError } from 'rxjs/operators'; import { MoviesService } from './movies.service';@Injectable() export class MovieEffects {loadMovies$ = createEffect(() => this.actions$.pipe(ofType('[Movies Page] Load Movies'),mergeMap(() => this.moviesService.getAll().pipe(map(movies => ({ type: '[Movies API] Movies Loaded Success', payload: movies })),catchError(() => EMPTY)))));constructor(private actions$: Actions,private moviesService: MoviesService) {} }loadMovies$ 效果通過 Actions 流監聽所有 dispatch 的 action,但只對使用 ofType 操作符的 [Movies Page] Load Movies 事件感興趣。
我們必須使用 ofType 來過濾事件,應該通過構造函數依賴注入得到的 action 實例是一個單例,默認會捕捉到系統所有 dispatch 的事件。
然后使用 mergeMap 運算符將 action 流展平,并映射到新的可觀察對象中。 MoviesService#getAll() 方法返回一個 observable,該 observable 將電影映射到成功的新 action,如果發生錯誤,當前返回一個空的 observable。
當需要更改狀態時,action 被分派到 Store,在那里它可以由 reducer 處理。 在處理可觀察流時處理錯誤也很重要,這樣 effect 才能繼續運行。
Registering root effects
編寫 Effects 類后,必須注冊它,以便效果開始運行。 要注冊根級 effects,請將 EffectsModule.forRoot() 方法與您的 effect 數組添加到您的 AppModule。
下面是 app.module.ts 的例子:
import { EffectsModule } from '@ngrx/effects'; import { MovieEffects } from './effects/movie.effects';@NgModule({imports: [EffectsModule.forRoot([MovieEffects])], }) export class AppModule {}即使您沒有注冊任何根級效果,也必須將 EffectsModule.forRoot() 方法添加到您的 AppModule 導入中。
下面的代碼來自 Spartacus 的 app.module.ts:
效果在 AppModule 加載后立即開始運行,以確保它們盡快偵聽所有相關操作。
Registering feature effects
對于功能模塊,通過在 NgModule 的導入數組中添加 EffectsModule.forFeature() 方法來注冊你的 effect。
例子:
import { EffectsModule } from '@ngrx/effects'; import { MovieEffects } from './effects/movie.effects';@NgModule({imports: [EffectsModule.forFeature([MovieEffects])], }) export class MovieModule {}通過 forRoot() 或 forFeature() 多次運行效果類(例如通過不同的延遲加載模塊)不會導致效果多次運行。 forRoot() 和 forFeature() 加載的效果之間沒有功能差異; 函數之間的重要區別在于 forRoot() 設置 Effects 所需的 providers 程序。
更多Jerry的原創文章,盡在:“汪子熙”:
總結
以上是生活随笔為你收集整理的如何编写第一个 ngrx Effect 类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大连理工大学有哪些专业
- 下一篇: 新年七言对联