在调用 api 之前检查对象的存储

check store for object before calling api

你知道他们怎么说你不需要状态管理直到你知道你需要它。事实证明我的项目需要它。所以我需要一些关于最佳实践的帮助,因为我正在将 ngxs 添加到现有的 angular 项目中。

我有一个名为 getServiceDetail 的操作,我的状态模型有一个名为 DriverListsStopInfoViewModel 的对象列表。这些对象中的每一个都有一个唯一的 ID。使用组件的 html 模板使用 属性 currentStopDetail 的选择器,这是在我的操作中设置的状态 属性。

目标:

在我的操作中,我想检查我商店中的对象列表,以查看是否存在具有相同 ID 的对象和 return 该对象,如果不存在,则调用 api 得到它。

示例:

以下代码有效,但我想听听这是否是正确的方法。如果找到了,我什至需要 return 动作函数中的对象,还是我可以只使用补丁状态将它分配给 currentStopDetail

export interface SignServiceStateModel {
  searchResults: ServiceSearchModel[];
  driverStopsDetails: DriverListsStopInfoViewModel[];
  driverStopsList: DriverListsStopsViewModel[];
  driverStopsMarkers: DriverStopsMarkerViewModel[];
  currentStopDetail: DriverListsStopInfoViewModel;
}

const SIGNSERVICE_STATE_TOKEN = new StateToken<SignServiceStateModel>(
  'signservice'
);

@State<SignServiceStateModel>({
  name: SIGNSERVICE_STATE_TOKEN,
  defaults: {
    searchResults: [],
    driverStopsDetails: [],
    driverStopsList: [],
    driverStopsMarkers: [],
    currentStopDetail: null
  },
})
@Injectable()
export class SignServiceState {
  constructor(private driverListsService: DriverListsService) {}

  
  @Action(DriverList.GetServiceDetail)
  getServiceDetail(
    ctx: StateContext<SignServiceStateModel>,
    action: DriverList.GetServiceDetail
  ) {
    if (action.serviceId === undefined || action.serviceId <= 0) {
      return;
    }
    // check if record already in list and return
    const currentState = ctx.getState();
    const existingStopDetail  = currentState.driverStopsDetails.find(s => s.SignServiceId === action.serviceId);
    if (existingStopDetail  !== undefined) {
      const currentStopDetail = existingStopDetail;
      ctx.patchState({ currentStopDetail });
      return currentStopDetail;
    }
    // else get new record, add it to list and return
    return this.driverListsService.getDriverListsInfo(action.serviceId).pipe(
      tap((currentStopDetail) => {
        ctx.patchState({ currentStopDetail });
        ctx.setState(
          patch({
            driverStopsDetails: append([currentStopDetail])
          })
        );
      })
    );
  }


  @Selector()
  static currentStopDetail(state: SignServiceStateModel) {
    return state.currentStopDetail;
  }
}

我只包含了我所在州的相关代码 class

问题:

这是检查商店中是否有商品并在商品不存在时致电 api 的最佳方式吗?

提前致谢

简短的回答是肯定的,你在这里所做的是处理这种情况的典型方法(根据我的经验)。您可以进行一些改进:

do I even need to return the object from the action function if its found, or can I just use patch state to assign it to the currentStopDetail

不,您不会 return 来自这些操作处理程序的任何内容,除了 NGXS 可能会处理的 Observable 之外(因此在您的情况下,如果没有找到匹配项,您 return 从 API 获取它并修补状态的 Observable

此外,当您进行 API 调用时,您应该只需要对状态进行一次更新:

return this.driverListsService.getDriverListsInfo(action.serviceId).pipe(
  tap((result) => {
    ctx.setState(
      patch({
        currentStopDetails: result
        driverStopsDetails: append([result]),
      })
    );
  })
);