Angular应用中切换翻译文化时如何触发多个Effect?
Angular 13国际化切换时触发数据重载的优化方案
我正在开发一个支持国际化的Angular 13应用。切换文化时,所有静态资源会立即完成翻译,但由于部分翻译由API提供,需要触发相关数据的重载。
现有实现代码如下:
public languageChange(value: TranslationLanguage): void { this.store.dispatch(UpdatePreferredCultureRequestedAction({ value: value.cultureName })); this.translate.use(value.cultureName); } updatePreferredCulture$ = createEffect(() => this.actions$.pipe( ofType(UpdatePreferredCultureRequestedAction), concatMap(action => { return this.layoutInfoService.updatePreferredCulture(action.value).pipe( catchError(err => { this.validation.handleAndDisplayError(err); return of(Constants.defaultCultureName); }) ); }), switchMap((culture: string) => { return [UpdatePreferredCultureLoadedAction({ value: culture }), QuestionnaireListRequestedAction() // 触发重载翻译敏感数据 ]; })) );
现有方案存在以下问题:
- 违反NgRx最佳实践,Effect中返回多个Action
- 翻译相关Effect与大量业务Action耦合
- 新增需要翻译的API请求Action时,必须修改这个Effect
优化思路:利用文化切换完成的Action做广播,业务模块自行响应
1. 调整原有Effect,聚焦核心逻辑
修改updatePreferredCulture$ Effect,只负责完成文化更新的核心流程,返回单一的状态更新Action,不再耦合业务请求:
updatePreferredCulture$ = createEffect(() => this.actions$.pipe( ofType(UpdatePreferredCultureRequestedAction), concatMap(action => { return this.layoutInfoService.updatePreferredCulture(action.value).pipe( catchError(err => { this.validation.handleAndDisplayError(err); return of(Constants.defaultCultureName); }) ); }), map((culture: string) => UpdatePreferredCultureLoadedAction({ value: culture })) ));
2. 业务模块独立监听文化切换事件
每个包含翻译敏感数据的业务模块,单独创建Effect监听UpdatePreferredCultureLoadedAction,触发自身的数据重载请求。以问卷模块为例:
loadQuestionnaireOnCultureChange$ = createEffect(() => this.actions$.pipe( ofType(UpdatePreferredCultureLoadedAction), switchMap(() => QuestionnaireListRequestedAction()) ));
其他如产品列表、用户信息等模块,可按同样模式添加对应Effect,无需修改翻译核心逻辑。
3. 可选:统一翻译切换时机
可以将translate.use()的调用移至Effect中,确保文化状态更新与翻译切换的原子性,避免组件逻辑分散:
updatePreferredCulture$ = createEffect(() => this.actions$.pipe( ofType(UpdatePreferredCultureRequestedAction), concatMap(action => { return this.layoutInfoService.updatePreferredCulture(action.value).pipe( catchError(err => { this.validation.handleAndDisplayError(err); return of(Constants.defaultCultureName); }) ); }), tap((culture: string) => this.translate.use(culture)), map((culture: string) => UpdatePreferredCultureLoadedAction({ value: culture })) ));
优化后的优势
- 遵循NgRx单一职责原则,每个Effect只处理单一逻辑
- 翻译核心逻辑与业务模块完全解耦,无需在一处维护所有业务请求
- 新增业务模块时,仅需在自身模块添加监听Effect,不影响原有代码结构
- 代码职责清晰,便于后续维护和扩展
内容的提问来源于stack exchange,提问作者Alexei - check Codidact
相关产品推荐
相关产品推荐

