如何简化 NgRx 效果?唯一不同的是他们调用的服务方法-

How to simplify NgRx effects? Only difference the service method they call-

我从 NgRx 效果文件中获得了以下代码:

  registerUser$: Observable<Action> = createEffect(() =>
    this.actions$.pipe(
      ofType(AuthStoreActions.registerUser),
      switchMap(action => {
        return this.authService.registerWithEmailAndPassword(action.userCredentials).pipe(
          map(() => AuthStoreActions.authSuccess({ navigateTo: "authentication/restaurant" })),
          catchError(error => of(AuthStoreActions.setError({ error })))
        );
      })
    )
  );
  loginUser$: Observable<Action> = createEffect(() =>
    this.actions$.pipe(
      ofType(AuthStoreActions.loginUser),
      switchMap(action => {
        return this.authService.loginWithEmailAndPassword(action.userCredentials).pipe(
          map(() => AuthStoreActions.authSuccess({ navigateTo: "authentication/restaurant" })),
          catchError(error => of(AuthStoreActions.setError({ error })))
        );
      })
    )
  );

服务调用后两者都在做同样的事情。如何消除重复? 我还有一个其他的兄弟效果,它在收到服务器的响应后比这个例子做的更多,但除了他们调用的方法之外,他们做同样的事情。

使用 pipe 函数,您可以将这些授权存储操作符集中在一起。

函数组合的力量!

import { pipe } from "rxjs";

const handleAuth = pipe(
  map(() => AuthStoreActions.authSuccess({ navigateTo: "authentication/restaurant" })),
  catchError(error => of(AuthStoreActions.setError({ error }))));

loginUser$: Observable<Action> = createEffect(() =>
  this.actions$.pipe(
    ofType(AuthStoreActions.loginUser),
    switchMap(action => this.authService.loginWithEmailAndPassword(action.userCredentials).pipe(handleAuth)));

registerUser$: Observable<Action> = createEffect(() =>
    this.actions$.pipe(
      ofType(AuthStoreActions.registerUser),
      switchMap(action => this.authService.registerWithEmailAndPassword(action.userCredentials).pipe(handleAuth)));

我会说,保持原样,而不是想减少一些 LOC

与以下解决方案相比,原样解决方案更具可读性并且更容易对更改做出反应:

  loginUser$: Observable<Action> = createEffect(() =>
    this.actions$.pipe(
      ofType(AuthStoreActions.loginUser, AuthStoreActions.registerUser),
      switchMap(action => {
        return this.authService[action.serviceMethod](action.userCredentials).pipe(
          map(() => AuthStoreActions.authSuccess({ navigateTo: "authentication/restaurant" })),
          catchError(error => of(AuthStoreActions.setError({ error })))
        );
      })
    )
  );