1

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

鉴于此特定模型的唯一合理 id 是在创建文档时由我的后端逻辑定义的,我应该如何在前端的实体实现中定义 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是我需要用来引用实体的违规字段。

4

3 回答 3

1

现在我已经修改了reducer,使其不在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行动的实体方法一致。

于 2019-07-09T16:06:45.550 回答
1

在这种情况下,我将考虑 2 个选项:

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

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

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

  • 选项 2:实现乐观的创建(以获得更好的用户体验)

如果确实需要乐观更新或达到目标,id则前端应用程序应生成临时或永久更新:

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

  • 永久id可以由前端(例如UUID)生成,并发送给后端使用。

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

希望能帮助到你。

于 2019-07-09T14:17:50.733 回答
0

如果您在谈论 ngrx/entity,只需在创建 EntityAdapter 时指定一个 selectId 方法。 有关更多信息,请参阅:createentityadapter

 dexport const adapter: EntityAdapter<Location > = createEntityAdapter<Location>({
  selectId: (location: Location) => location.locationid,
});
于 2019-10-21T13:00:54.147 回答