组合两个选择器或在另一个效果中调用 Effect?

问题描述 投票:0回答:1

我有一个具有属性的项目列表。这是它的模型:

export interface Banner {
    id: number;
    name: string;
    channelId: string;
    language: string;
    zoneId: string;
    priority: number;
    fileId: string;
    startDate: Date;
    endDate: Date;
    active: boolean;
    labels: string[];
}

我的服务返回上述所有属性。但我必须调用第二个服务,该服务通过第一个服务响应中的 fileid 返回 image url

我正在使用 ngrx 状态管理。以下是我的行动:

export const getImageById = createAction( BannerActionTypes.GetImageById, props<{ id: string }>() ); export const getImageByIdSuccess = createAction( BannerActionTypes.GetImageByIdSuccess, props<{ url: string }>() ); export const getImageByIdFail = createAction( BannerActionTypes.GetImageByIdFail, props<{ error: Error | any }>() ); export const loadBanners = createAction( BannerActionTypes.LoadBanners, props<{ filter: Filter }>() ); export const loadBannersSuccess = createAction( BannerActionTypes.LoadBannersSuccess, props<{ response: BannerResponse }>() ); export const loadBannersFail = createAction( BannerActionTypes.LoadBannersFail, props<{ error: Error | any }>() );
我的效果是:

export class BannerEffect { constructor(private actions$: Actions, private bannersService: BannersService) { } loadBanners$ = createEffect(() => this.actions$.pipe( ofType(BannerActions.loadBanners), switchMap((s) => this.bannersService.getAll(s.filter).pipe( map((response) => BannerActions.loadBannersSuccess({ response })), catchError((error) => of(BannerActions.loadBannersFail({ error }))) ) ) ) ); getImage$ = createEffect(() => this.actions$.pipe( ofType(BannerActions.getImageById), switchMap((s) => this.bannersService.getImageById(s.id).pipe( map((url) => BannerActions.getImageByIdSuccess({ url })), catchError((error) => of(BannerActions.getImageByIdFail({ error }))) ) ) ) ); }
所以我的问题是,我应该在哪里组合这两个服务调用?
我应该在加载成功后在 loadBanners 效果中调用 getImageById 还是应该在选择器中将这两个结合起来?最好的方法是什么。
我想将带有图像 URL 的所有属性集中在一处。

angular typescript ngrx ngrx-store ngrx-effects
1个回答
0
投票
您还没有提供您的状态,所以目前我只是猜测它的形状。

让我们假设每个列表项都有一个类型

Banner

(即,它没有扩展)并且 
imageUrl
 始终可用并且确实必须处于全局状态。
在这种情况下,您的状态有问题,因为 required 
Banner
 的属性存储在其他地方。这肯定会导致您遇到一种情况,即您的状态中的数据不完整,并且您将被迫对第二个服务调用进行一些黑客重试。恕我直言,这是糟糕的状态设计,应该不惜一切代价避免。
选择器并不能解决问题,它只是通过添加额外的代码使问题变得更糟。

我将使用包含

Banner

 属性的 
imageUrl
 类型的扩展版本构建一个状态。然后我会在一个效果中链接服务调用,因此在执行结束时您会得到“全部或全部”。

© www.soinside.com 2019 - 2024. All rights reserved.