在 NgRx 中,在哪里将来自服务器的响应数据(通过副作用获得)转换为组件可以理解的状态?

In NgRx, where to transform the response data from a server (got through side effects) to a state which the component understands?

我是 NgRx 的新手,因此感到困惑。 我有一个简单的组件,它显示了一个对象列表,例如命令。 它使用 Effect 从后端获取要显示的订单列表。 唯一的问题是我想将来自 BE 的响应转换为要在组件中显示的简单对象列表。 我对在哪里转换它感到困惑。我看到 4 个选项:

  1. 在从后端获取列表的服务中对其进行转换 - 实施起来非常简单,不确定是否是最佳方式。
  2. 在效果中转换它 - 如果在这里那么为什么不在服务中?
  3. 使用减速器对其进行转换 - 似乎是一个有效的地方。
  4. 使用选择器对其进行转换 - 我们不需要视图状态,因为每次打开组件时视图状态都会从选择器派生。甚至可能让它变慢,因为它每次都必须转换状态。

这是我目前的理解。我想知道它是否正确,我也想知道处理这种情况的最佳实践,这在应用程序中似乎很常见。

这不是 ngrx 问题,而是客户端-服务器映射问题。

根据我的经验,最佳做法是尽可能靠近 api 映射 - 因此在这种情况下,在从 BE 获取它的服务中。

请注意,您还可以创建特定的映射服务,并从 API 服务调用它 - 这将取决于您的 API 服务的详细程度

你有:

  • 您需要列表的组件
  • 一个你做 http 请求的服务
  • 一个州,ngrx

步数:

  1. a) 从组件中派发一个动作——获取列表 b) 在组件中,监听 listAction(接收新数据)

     ngOnInit() {
         this.store.dispatch(getListAction); // this will fire the action
    
     this.store.pipe(
        select(fromStore.selectList)
     ).subscribe(yourList => {
        // here you have the list
     });
    

    }

  1. actions.ts

     export enum Types {
           GET_LIST = '[Store Type] Get List',
           GET_LIST_SUCCESS = '[Store Type] Get List Success',
           GET_LIST_FAILED = '[Store Type] Get List Failed',
         } 
    
     export const getListAction = createAction(
       Types.GET_LIST // this will be fired from component, and will fire the store effect
     );
     export const getListSuccessAction = createAction(
       Types.GET_LIST_SUCCESS, // this will be fired when service return the list
       props<{list: obj_type[]}>
     );
    export const getListSuccessAction = createAction(
       Types.GET_LIST_FAILED, // this will be fired when service throws error
       props<{msg: string}>
     );
    
  2. effects.ts

    @Injectable()
    export class MyEffects {
    
     constructor(service: YourService) {
    }
        
         getList$ = createEffect(() =>
            this.actions$.pipe(
              ofType(getListAction),
              switchMap(() =>
                this.your_service.getList().pipe(
                  tap((list) => getListSuccessAction({list})),
                  catchError((error) =>
                    of(getListFailedAction({ msg: error.message }))
                  )
                )
              )
            )
          );
        }
  1. reducer.ts

    export const reducer = createReducer(
      initialState,
      on(getListAction, (state) => ({
        ...state,
        request: PENDING
      })),
      on(getListSuccessAction, (state, { list}) => ({
        // your component store.pipe(select) will be fired with data from here
        ...state,
        list: 
        request: COMPLETED
      })),
      on(getListFailedAction, (state, { msg }) => ({
        ...state,
        error: {msg},
        request: FAILED
      }))
    );````
    
    
  2. selectors.ts

    export const selectState = (state: AppState) => state;
    
    export const selectList =
      createSelector(selectState , (state) =>
        state.list);