从NgRx中的RESTful API“逐步”加载实体

时间:2019-03-07 00:37:25

标签: angular rest api redux ngrx

我正在使用Angular 7和NgRx构建应用程序,并使用Entity State Adapter进行尝试。

我想通过ID向NgRx请求一个或多个对象,但是如果它不在存储中,我想从RESTful API中请求它,然后将其放在NgRx存储中。

我构建了RESTful API,可以使用ID数组请求任意数量的对象,并且我了解了如何使用一个或多个ID从NgRx中选择对象,并且知道如何使用效果将数据加载到NgRx中和减速器。

但是,如何使系统正常工作,以便如果我通过ID请求一个或多个对象,它将从存储中返回现有的对象(如果存在)和/或通过从RESTful请求存储来更新存储API。

有很多数据,所以预装所有数据效率低下,但是有多种用途,我需要显示许多列表,或显示单个列表,或按ID显示相关对象,等等。< / p>

例如:

列表页面希望ID 0-10显示在列表中。向商店询问,商店没有它们,因此可以从API获取它们。现在商店有0-10个,列表显示了它们。

“详细信息”页面需要ID 10,商店从上次加载列表页面时获得了ID(在本例中为ID),但由于它们是相关的,它也希望获得ID 13和14,因此我将要求输入10、13以及14。该商店有10个,因此可以立即显示,但是必须从RESTful API请求13和14,并在它们返回时填充商店。

列表页面显示“页面2”,即ID 11-20,并且商店中已经有ID 13和14,因此只需从API中获取11-12和15-20,等等。

乘以成千上万,因为有太多数据无法一次全部加载到本地。

我的错误解决方案:

我想实现这一目标的方法是为id []提供一个选择器,然后该选择器返回商店中已经存在的所有ID,然后为缺少的ID调度一个动作,以便效果器和简化器发挥作用。我不知道如何让选择器分派动作(如果那是正确的方法)。

或者,在要求数据的组件中,它为没有从选择器返回的任何数据调度操作,但是将逻辑放在组件中并不是一个好地方。

我考虑过将其放入服务中,这似乎很合理,但是我不确定如何在不重复代码的情况下将存储/状态传达给组件和服务,以及/或者如何通过服务将状态更新传递给组件,以及其他奇怪的实时状态问题。

1 个答案:

答案 0 :(得分:1)

您可以从选择器中返回缺少的ID(而不是找到的ID的列表,返回一个包含找到的实体列表和缺少的ID的数组的对象,如果有的话),然后在订阅中(如果您使用$ async,则点击)管道)调度将通过效果获取缺少ID的操作。

类似这样的东西:

export const $mySelector = createSelector($someEntitySelector, (entities, props: { ids: string[] }) => {
  const items = [];
  const missingIds = [];

  props.ids.map(id => {
    if (entities[id]) {
       items.push(entities[id]);
    } else {
       missingIds.push(id);
    }

  })

  return {
    items,
    missingIds
  }
});

在组件中:

  this.store$.select($mySelector).pipe(
    tap({items, missingIds} => {
       if (missingIds) {
         // dispatch action that will trigger the effect
       }
    })

  )

您肯定需要处理服务器上没有ID的情况(如果该服务找不到最安全的选择,那就是删除该ID,这样它就不会无缘无故再次调用该服务)