微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ngrx 从效果更新状态

如何解决ngrx 从效果更新状态

我有 ngrx 存储设置,用于存储当前活动的用户用户的语言环境。根据用户区域设置,我的拦截器将在所有 API 调用中注入 X-LOCALE 标头。当调用选择用户的操作时,我首先调用单独的 API 来获取用户的语言环境,将该语言环境传递给拦截器,然后继续调用其余的 API(此时应注入 X-LOCALE 标头)。问题:如何从 user-effects.ts 触发状态更改?

user-reducer.ts

export interface UseRSState extends EntityState<UserInfo> {
  loading: boolean;
  currentUser: UserInfo;
  locale: string;
}
const usersReducer = createReducer(
  INITIAL_STATE,on(actions.fetchUser,...bunch of other actions...,(state) => ({ ...state,loading: true })
);

user-actions.ts

...bunch of actions
export const fetchUser = createAction('[USERS] Fetch User Request',props<{ uuid: string }>());

user-effects.ts

@Injectable()
export class UsersEffects {
  fetchUser$ = createEffect(() =>
    this.actions$.pipe(
      ofType(usersActions.fetchUser),switchMap(({ uuid }) => {
        // here we would read user locale
        return this.useRSService.fetchUserLocale(uuid).pipe(
          map((locale) => {
            // ******* here i need to update locale in the state ********
            return uuid;
          });
        }),);
    }),switchMap((uuid) => {
      // all calls from here on should have "X-LOCALE" header injected
      return forkJoin([
        this.useRSService.fetchUser(uuid),this.useRSService.fetchUserCards(uuid),this.useRSService.fetchUserPermissions(uuid),]).pipe(
        map(([userDto,cards,permissions]) => {
          const userInfo = { ...userDto,permissions };
          return usersActions.fetchUserSuccess({ userInfo });
        }),catchError((error) => of(usersActions.fetchUserFailure({ error }))),),);

这里 locale.interceptor.ts 会注入头文件

@Injectable()
  export class HttpHeadersInterceptor implements HttpInterceptor {
    constructor(private store$: Store<UseRSState>) {
      this.store$.pipe(select((state) => state.locale)).subscribe((locale: string) => {
        this.locale = locale;
      });
    }
    private locale: string;

    intercept(req: HttpRequest<any>,next: HttpHandler): Observable<HttpEvent<any>> {
      const defaultHeaders = { Accept: 'application/json,text/plain' };

      if (this.locale) {
        defaultHeaders['X-LOCALE'] = this.locale;
      }

      const authReq = req.clone({ setHeaders: defaultHeaders });

      return next.handle(authReq);
    }
  }

解决方法

好吧,我不确定这是否是最佳实践,但您仍然可以从 switchMap 内调度操作,直接从 map 或您可以将其更改为 {{1 }} 因为没有实际的映射,所以它只是一个副作用。像这样的东西。

tap

正如我所说,我不确定这是否是最佳实践,但在我的项目中,我曾多次使用类似的方法。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。