在 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 个选项:
- 在从后端获取列表的服务中对其进行转换 - 实施起来非常简单,不确定是否是最佳方式。
- 在效果中转换它 - 如果在这里那么为什么不在服务中?
- 使用减速器对其进行转换 - 似乎是一个有效的地方。
- 使用选择器对其进行转换 - 我们不需要视图状态,因为每次打开组件时视图状态都会从选择器派生。甚至可能让它变慢,因为它每次都必须转换状态。
这是我目前的理解。我想知道它是否正确,我也想知道处理这种情况的最佳实践,这在应用程序中似乎很常见。
这不是 ngrx 问题,而是客户端-服务器映射问题。
根据我的经验,最佳做法是尽可能靠近 api 映射 - 因此在这种情况下,在从 BE 获取它的服务中。
请注意,您还可以创建特定的映射服务,并从 API 服务调用它 - 这将取决于您的 API 服务的详细程度
你有:
- 您需要列表的组件
- 一个你做 http 请求的服务
- 一个州,ngrx
步数:
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
});
}
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}>
);
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 }))
)
)
)
)
);
}
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
}))
);````
selectors.ts
export const selectState = (state: AppState) => state;
export const selectList =
createSelector(selectState , (state) =>
state.list);
我是 NgRx 的新手,因此感到困惑。 我有一个简单的组件,它显示了一个对象列表,例如命令。 它使用 Effect 从后端获取要显示的订单列表。 唯一的问题是我想将来自 BE 的响应转换为要在组件中显示的简单对象列表。 我对在哪里转换它感到困惑。我看到 4 个选项:
- 在从后端获取列表的服务中对其进行转换 - 实施起来非常简单,不确定是否是最佳方式。
- 在效果中转换它 - 如果在这里那么为什么不在服务中?
- 使用减速器对其进行转换 - 似乎是一个有效的地方。
- 使用选择器对其进行转换 - 我们不需要视图状态,因为每次打开组件时视图状态都会从选择器派生。甚至可能让它变慢,因为它每次都必须转换状态。
这是我目前的理解。我想知道它是否正确,我也想知道处理这种情况的最佳实践,这在应用程序中似乎很常见。
这不是 ngrx 问题,而是客户端-服务器映射问题。
根据我的经验,最佳做法是尽可能靠近 api 映射 - 因此在这种情况下,在从 BE 获取它的服务中。
请注意,您还可以创建特定的映射服务,并从 API 服务调用它 - 这将取决于您的 API 服务的详细程度
你有:
- 您需要列表的组件
- 一个你做 http 请求的服务
- 一个州,ngrx
步数:
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 });
}
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}> );
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 }))
)
)
)
)
);
}
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 })) );````
selectors.ts
export const selectState = (state: AppState) => state;
export const selectList =
createSelector(selectState , (state) =>
state.list);