«Прогрессивная» загрузка сущностей из RESTful API в NgRx - PullRequest
0 голосов
/ 07 марта 2019

Я создаю приложение, используя Angular 7 и NgRx, и пробую это с помощью адаптера Entity State.

Я хочу запросить один или несколько объектов из NgRx по идентификатору, но если его нет в магазине, я хочу запросить его у RESTful API, а затем поместить в хранилище NgRx.

Я создал RESTful API и могу запрашивать любое количество объектов с массивом идентификаторов, и я прочитал о том, как я могу выбирать объекты из NgRx, используя один или несколько идентификаторов, и я знаю, как загружать данные в NgRx, используя эффекты и редукторы.

Но как я могу заставить систему работать так, чтобы, если я запрашиваю один или несколько объектов по идентификатору, она возвращала существующие из хранилища, если они существуют, и / или обновляла хранилище, запрашивая их у RESTful? API.

Там много данных, поэтому предварительная загрузка их неэффективна, но есть смешанные способы, где мне нужно будет показать список из многих, или показать один, или показать связанные объекты по идентификатору и т. Д.

Например:

Страница списка хочет, чтобы идентификаторы 0-10 отображались в списке. Спросите у магазина, у магазина их нет, поэтому он получает их из API. Теперь в магазине 0-10, и список отображает их.

Страница сведений требует идентификатора 10, в магазине он есть от предыдущей загрузки страницы списка (в данном случае), но также требуются идентификаторы 13 и 14, потому что они связаны, поэтому я собираюсь попросить 10, 13 , и 14. Хранилище имеет 10, поэтому оно отображается немедленно, но должно запросить 13 и 14 из API RESTful и заполняет хранилище, когда они возвращаются.

На странице списка отображается «страница 2», то есть идентификаторы 11-20, а 13 и 14 уже находятся в магазине, так что нужно просто получить 11-12 и 15-20 из API и т. Д.

Умножается на тысячи, потому что данных слишком много, чтобы загружать их локально одновременно.

Мое плохое решение:

Моя мысль о достижении этого заключается в том, чтобы иметь селектор для идентификатора [], и этот селектор возвращает те идентификаторы, которые уже существуют в хранилище, а затем отправляет действие для отсутствующих идентификаторов, чтобы эффекты и редукторы выполняли свою работу. Я не знаю, как заставить селектор отправлять действие (если это даже правильный подход).

С другой стороны, в компоненте, запрашивающем данные, он отправляет действие для любых данных, которые не возвращаются из селектора, но помещение этой логики в компонент не является подходящим местом для него.

Я думал о том, чтобы поместить его в службу, что кажется рациональным, но я не уверен, как тогда передать хранилище / состояние компоненту и службе без необходимости дублировать кучу кода и / или как передавать обновления состояния через службу компоненту и другие странные проблемы состояния в реальном времени.

1 Ответ

1 голос
/ 07 марта 2019

Вы можете вернуть отсутствующие идентификаторы из селектора (вместо списка найденных идентификаторов вернуть объект, содержащий список найденных объектов и массив отсутствующих идентификаторов, если таковые имеются), а затем в подписке (или нажмите, если вы используете $ async pipe) отправляет действие, которое извлекает недостающие идентификаторы через Effect.

Примерно так:

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
       }
    })

  )

Вам определенно нужно будет обработать случай, когда на сервере нет идентификатора (если служба не находит его, безопаснее всего удалить этот идентификатор, чтобы он больше не вызывал службу без причины)

...