Как расширить ngrx / data с помощью Entity Effects? - PullRequest
2 голосов
/ 17 февраля 2020

При преобразовании приложения для использования управления состоянием ngrx я решил управлять состоянием некоторых моделей с помощью ngrx / data через EntityMaps. Пока это работает нормально, однако, когда все становится немного сложнее, например, на основе полученных данных модели с удаленного сервера, мне нужны связанные модели (заказы-> продукты или в формате конечной точки REST GET orders/:id/products)

I чувствую себя застрявшим - я знаю, что есть ngrx / эффекты для запуска действий, которые загружают другие данные при использовании ngrx, и в этом ngrx / data guide `EntityEffects упоминается для запуска побочных эффектов с действиями, но кроме этого Документы, похоже, находятся в процессе разработки и сейчас мне не очень помогают.

К сожалению, нет ничего особенного в расширении EntityEffects для настройки извлечения удаленных данных. Конечно, я мог бы go вплоть до реализации селекторов, действий, редукторов, воздействовать стандартным способом ngrx, но не в этом вся суть ngrx / data, чтобы упростить обработку состояний с меньшим количеством стандартного кода и действовать как обертка вокруг ngrx, скрывающая код по умолчанию / шаблон, но все же предоставляющий способ использования базовых частей?

Поскольку я относительно новичок в ngrx и управлении состоянием в целом, я не знаю, где именно искать для передового опыта или рекомендуемого решения, как эта проблема решается.

Итак мои вопросы в основном:

  1. Как я могу одновременно использовать ngrx / data и загрузить (связанные) данные модели с помощью ngrx / Effects или EntityEffects?
  2. Где я могу расширить соответствующие сервисы / классы, не прибегая к реализации каждого редуктора / действия вручную, и вместо этого позволяя ngrx / data позаботиться об этом?

Я уже искал Stackoverflow, Gitter и спросил коллег, но безуспешно - или мне все сложнее, чем должно быть? Если да, то я благодарен за любую помощь.

Примечание: Этот вопрос особенно касается ngrx /

1 Ответ

1 голос
/ 28 февраля 2020

Это открытая проблема github https://github.com/ngrx/platform/issues/1934


Однако я считаю, что есть способ сделать это, не начав с нуля, используя метод EntityCacheDispatcher saveEntities Сохранение с EntityCacheDispatcher.saveEntities () .

Чтобы дать вам представление о том, как это работает при использовании по назначению, вот мой эффект порядка сохранения для недавнего проекта

  saveOrder$ = createEffect(() =>
    this.actions$.pipe(
      ofType(PurchaseOrderActions.saveOrder),
      switchMap(() => {
        const order$ = this.store.pipe(select(selectHeader));
        const orderLines$ = this.store.pipe(select(allLines));
        const deletedOrderLines$ = this.store.pipe(select(selectDeletedLines));
        return combineLatest([order$, orderLines$, deletedOrderLines$]).pipe(
          first(),
          switchMap(([order, lines, deletedLines]) => {
            const changes: ChangeSetItem[] = [
              cif.upsert("PurchaseOrder", order),
              cif.upsert("PurchaseOrderLine", lines),
              cif.delete("PurchaseOrderLine", deletedLines)
            ];
            return this.entityCacheDispatcher
              .saveEntities(changes, `${this.baseURL}order`)
              .pipe(
                map(changesResponse =>
                  PurchaseOrderActions.saveOrderSuccess({
                    header: changesResponse.changes[0]
                      .entities[0] as PurchaseOrder,
                    lines: changesResponse.changes[1]
                      .entities as PurchaseOrderLine[]
                  })
                )
              );
          })
        );
      })
    )
  );

Потенциальная дорожная карта

  1. Создайте свое пользовательское действие, например, введите "[OrderProductsPage ONINIT] ONINIT"
  2. Создайте эффект, который вызывает saveEntities
// include in custom action payload and get this id here
const id; 

// changeSet with empty changes
const changeSet = {
    changes: [],
    tag: "CUSTOM_GET_PRODUCTS" // hook for defining custom behaviour
}
this.entityCacheDispatcher.saveEntities(changeSet, `orders/${id}/products`)
Расширьте EntityCacheDataService и переопределите метод saveEntities, чтобы сначала проверить, является ли тег CUSTOM_GET_PRODUCTS, иначе вызовите super.saveEntities (changeSet, url). Если тег равен CUSTOM_GET_PRODUCTS, то вызовите, чтобы получить http и карту каналов для изменения. Установите с помощью ChangeSetOperation.Add

Ссылка на super.saveEntities ()

Обновление

Это работает, но немного более хакерски, чем хотелось бы

Stackblitz

...