Как определить selectId для адаптера объекта, когда соответствующий идентификатор определен на серверной части? - PullRequest
0 голосов
/ 09 июля 2019

Я отправляю действие / редуктор upsert в свой магазин, чтобы добавить новую запись в состояние, и есть эффект, который вызывает бэкэнд и добавляет запись / документ в мой экземпляр mongodb.

Учитывая, что единственный разумный идентификатор для этой конкретной модели определяется моей бэкэнд-логикой во время создания документа, как я должен определить selectId в моей реализации сущности в моем интерфейсе?

ВВ момент, когда элемент добавляется в состояние с помощью id: undefined, и я получаю предупреждение:

entity.js: 76 @ ngrx / entity: Объект, переданный реализации selectId, вернул неопределенное значение.Вероятно, вам следует предоставить собственную реализацию selectId.

Мой адаптер определен как:

export const adapter: EntityAdapter<PublishedData> = createEntityAdapter<
  PublishedData
>({ selectId: (publishedData: PublishedData) => publishedData.doi });

, а соответствующий эффект:

@Effect()
  UpsertPublishedData$ = this.actions$.pipe(
    ofType<UpsertPublishedData>(PublishedDataActionTypes.UpsertPublishedData),
    switchMap(action => this.publishedDataApi.create(action.payload.publishedData)
    .pipe(mergeMap((data: PublishedData) => [ new UpsertPublishedData({ publishedData: data }),
      this.publishedDataApi.register(data[0].doi)]),
    catchError(err => of(new FailedPublishedDataAction(err)))))
  );

publishedData.doi - это поле с ошибками, которое мне нужно использовать для ссылки на сущность.

Ответы [ 2 ]

0 голосов
/ 09 июля 2019

На данный момент я изменил редуктор, чтобы не добавлять запись в состояние при первом проходе, где поле id (doi) не определено.

case PublishedDataActionTypes.UpsertWaitPublishedData: {
  if (action.payload.publishedData && action.payload.publishedData.doi) {
    return adapter.upsertOne(action.payload.publishedData, state);
  }
  return state;
}

из этого первоначально:

  case PublishedDataActionTypes.UpsertPublishedData: {
      return adapter.upsertOne(action.payload.publishedData, state);
    }

Это гарантирует, что запись в состоянии соответствует записи в базе данных.Этот подход все еще соответствует сущностному подходу, согласно которому никаких дополнительных действий UpsertPublishedDataSuccess не требуется.

0 голосов
/ 09 июля 2019

В этом случае я рассмотрю 2 варианта:

  • Вариант 1: реализовать пессимистическое создание (чтобы не усложнять)

Когдапользователь создает новую запись, например, действие AddRecord вызывает POST запрос к интерфейсу API.При успешном ответе выдается новое действие AddRecordSuccess, которое добавляет новую созданную запись (с отправкой id бэкэндом) в хранилище с @ngrx/entity.

Во время процесса создания (запрос к бэкэнду) загрузчикоминдикатор должен отображаться для уведомления пользователя.

  • Вариант 2: реализовать оптимистическое создание (для лучшего UX)

Если оптимистическое обновление действительнопотребность или цель, которую нужно достичь, временное или постоянное id должно быть сгенерировано внешним приложением:

  • временное id используется внутри хранилища для управления объектами, которые будутсинхронизированы.Когда сущности создаются бэкэндом, id должен обновляться или дополняться постоянным бэкэндом id.

  • постоянный id может быть сгенерирован внешним интерфейсом (например, UUID) и отправлен для использования внутренним сервером.

Inво всех случаях @ngrx/entity нужен идентификатор (number или string) для идентификации и управления сущностями в хранилище.

Надеюсь, это поможет.

...