官方网站要从您的组件中隔离副作用,您必须创建一个Effects类来侦听事件并执行任务。Effect是一个可注入的服务类,具有不同的部分:一个可注入的Actions服务,它提供在reduce的最新状态之后调度的所有操作的可观察流。如下图所示:使用createEffect函数将元数据附加到可观察流。元数据用于注册对存储流的订阅。从效果流返回的任何操作都将被分派回Store。使用可管道化的ofType运算符过滤操作。ofType运算符将一种或多种操作类型作为参数来过滤要执行的操作。如下图所示:effects订阅一个Storeobservable。服务被注入到效果中以与外部API交互并处理流。看一个实际的效果实现例子: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()exportclassMovieEffects{loadMovies$=createEffect(()=>this.actions$.pipe(ofType('[电影页面]加载电影'),mergeMap(()=>this.movi??esService.getAll().pipe(map(movies=>({type:'[MoviesAPI]MoviesLoadedSuccess',payload:movies})),catchError(()=>EMPTY)))));constructor(privateactions$:Actions,privatemoviesService:MoviesService){}}loadMovies$该效果通过Actions流侦听所有调度动作,但仅对那些使用ofType运算符的[MoviesPage]LoadMovies事件感兴趣。我们必须使用ofType来过滤事件。通过构造函数依赖注入应该得到的action实例是一个单例,默认会捕获系统所有的dispatch事件。然后使用mergeMap运算符将操作流展平并映射到一个新的可观察对象中。MoviesService#getAll()方法在成功时返回一个将电影映射到新操作的可观察对象,如果发生错误则返回一个空的可观察对象。当需要更改状态时,操作会被分派到Store,在那里它可以由reducers处理。在处理可观察流时处理错误也很重要,这样效果才能继续运行。注册根效果在编写Effects类之后,必须注册它以便效果开始运行。要注册根级效果,请将带有效果数组的EffectsModule.forRoot()方法添加到AppModule。这是一个示例app.module.ts:import{EffectsModule}from'@ngrx/effects';从'./effects/movie.effects'导入{MovieEffects};@NgModule({imports:[EffectsModule.forRoot([MovieEffects])],})exportclassAppModule{}即使您没有注册任何根级效果,您也必须将EffectsModule.forRoot()方法添加到您的AppModule进口。下面的代码来自Spartacus的app.module.ts:效果会在AppModule加载后立即开始运行,以确保它们尽快侦听所有相关操作。注册功能效果对于功能模块,通过将EffectsModule.forFeature()方法添加到NgModule导入数组来注册您的效果。示例:从'@ngrx/effects'导入{EffectsModule};从'./effects/movie.effects'导入{MovieEffects};@NgModule({imports:[EffectsModule.forFeature([MovieEffects])],})exportclassMovieModule{}通过forRoot()或forFeature()多次运行效果类(例如通过不同的延迟加载模块)不会导致效果运行多次。forRoot()和forFeature()加载的效果之间没有功能差异;函数之间的重要区别是forRoot()设置Effects所需的提供者程序。更多Jerry原创文章在这里:《王子熙》:
