在后端定义相关ID时,如何为实体适配器定义selectId?

时间:2019-07-09 12:40:19

标签: angular api ngrx id ngrx-entity

我正在商店上调度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是我用来引用实体的有问题的字段。

3 个答案:

答案 0 :(得分:0)

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

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

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

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

  • 选项2:实施乐观的创建(以获得更好的UX)

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

    商店内部使用
  • 临时id来管理要同步的实体。通过后端创建实体时,id应该由永久后端id更新或完成。

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

在所有情况下,number需要一个标识符(string{"tableName":"employee", "data": {"empname":"john" ,"empId" :"100" ,"sal" : "1000" } } )来标识和管理商店中的实体。

希望有帮助。

答案 1 :(得分:0)

现在,我已经修改了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动作。

答案 2 :(得分:0)

如果您正在谈论ngrx /实体,则只需在创建EntityAdapter时指定selectId方法即可。  see for more info: createentityadapter

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