在后端定义了相关id后,如何为entity adapter定义selectId?

How to define selectId for entity adapter when the relevant id is defined on the backend?

我正在我的商店中调度 upsert 操作/reducer 以向状态添加新记录,并且有一个效果会调用后端并将记录/文档添加到我的 mongodb 实例。

鉴于此特定模型的唯一合理 ID 是由我的后端逻辑在创建文档时定义的,我应该如何在前端的实体实现中定义 selectId?

目前,一个项目被添加到 id: undefined 状态,我收到警告:

entity.js:76 @ngrx/entity: The entity passed to the selectId implementation returned undefined. You should probably provide your own selectId implementation.

我的适配器定义为:

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 个选项:

  • 选项 1:实施悲观创建(保持简单)

当用户创建新记录时,例如 AddRecord 的操作会调用对后端 api 的 POST 请求。成功的响应发出一个新操作 AddRecordSuccess,它将新创建的记录(后端发送 id)添加到存储 @ngrx/entity.

在创建过程中(向后端请求),应显示加载器指示器以通知用户。

  • 选项 2:实施乐观创建(为了更好的用户体验)

如果确实需要或 objective 需要乐观更新,则 front-end 应用程序应生成临时或永久 id :

  • temporary id 用于store内部管理要同步的实体。当后端创建实体时,id 应该由永久后端 id 更新或完成。

  • 永久id可以由front-end(例如UUID)生成,并发送到 被后端使用。

在所有情况下,@ngrx/entity 都需要一个标识符(numberstring)来识别和管理商店中的实体。

希望对您有所帮助。

现在我已经修改了 reducer,以便在 id 字段 (doi) 未定义的第一遍中不将记录添加到 state。

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 操作。

如果您在谈论 ngrx/entity,只需在创建 EntityAdapter 时指定一个 selectIon 方法。 see for more info: createentityadapter

 dexport const adapter: EntityAdapter<Location > = createEntityAdapter<Location>({
  selectId: (location: Location) => location.locationid,
});