我有一个 struct 如下的对象:

{
 parent1: [
     {childId: 1},
     {childId: 2}
    ],
 parent2: [
     {childId: 3},
     {childId: 4}
    ],
 parent3: [
     {childId: 5},
     {childId: 6}
 ]
}

以下服务:

addFamily(data: any): Observable<Family> {
     const body = JSON.stringify(data);
     return this.httpClient
          .post<Family>(this.apiUrl + '/family', body, this.httpOptions)
}
addParent(data: any): Observable<Parent> {
     const body = JSON.stringify(data);
     return this.httpClient
          .post<Parent>(this.apiUrl + '/parent', body, this.httpOptions)
}
addChild(data: any): Observable<Child> {
     const body = JSON.stringify(data);
     return this.httpClient
          .post<Child>(this.apiUrl + '/child', body, this.httpOptions)
}

数据库中有相应的"family"、"parent"和"child"表,我想使用RxJS高阶映射运算符相应地发布到这些表中的每一个,以根据以前的调用构建数据响应.这个 idea 是:

  1. 拨打addFamily()并返回新的familyId
  2. 通过familyId呼叫addParent()并返回新的parentId
  3. for each 创建的子项调用addChild()传入parentId

对示例对象执行操作后,将出现:

  • 添加了6个子元素(FK child\u parent)
  • 添加3个家长(FK parent_family)
  • 添加了1个系列

目前,代码库正在使用多个嵌套的订阅来执行上述任务,这就是为什么我研究RxJS并从类似的question个代码中偶然发现了下面的代码.

private getData(): Observable<VmData> {

     return this.service.getSomeData().pipe(
                 switchMap(session => this.service.getUserData(session.userId).pipe(
                      switchMap(user => this.service.getMetaData(user.id).pipe(
                           // by nesting, map has access to prior responses
                           map(userMeta => this.buildVmData(session, user, userMeta))             
                      ))
                 )),
                 tap(() => this.isLoading = false)
     );
}

如果是一个家庭,上述代码将起作用-&gt;单亲-&gt;一个子元素,但我如何修改它以添加一个家庭,循环遍历每个家长,并在该家长下添加每个子元素?非常感谢您的帮助.非常感谢.

推荐答案

如果你把问题分解成更小的可组合块呢?我可以看到3个功能:

  1. createFamily将呼叫addFamily(),然后为该家庭的每位家长使用createParent.
  2. createParent将呼叫addParent(),然后为该家长的每个子元素使用createChild.
  3. createChild将呼叫addChild()

像这样的

function createFamily(family) {
  return defer(() => {
    const familyId = generateFamilyId();

    return addFamily({ familyId });
  }).pipe(
    switchMap((result) => {
      const { familyId } = result;
      const parentCreations = Object.entries(family).map(
        ([parentId, children]) => createParent({ familyId, parentId, children })
      );

      return merge(...parentCreations);
    })
  );
}

function createParent(parent) {
  return addParent(parent).pipe(
    switchMap(() => {
      const { familyId, parentId, children } = parent;

      const childrenCreations = children.map(({ childId }) =>
        createChild({
          familyId,
          parentId,
          childId,
        })
      );
      return merge(...childrenCreations);
    })
  );
}

function createChild(child) {
  return addChild(child);
}

在这种情况下,createFamily(family)将返回一个Observable<Child>,发出创建的所有子级.通过更改每个函数中的.pipe(个,您可以轻松地将其转换为您需要的任何内容(这就是为什么我还将createChild保留为addChild的单独函数,其 idea 是如果需要,您可以在那里进行转换)

Angular相关问答推荐

文件阅读器未正确给出某些CSV文件的结果

Angulat 17@ngrx/Signals或全球服务,用什么?

Angular v12:Uncatch(in promise):ReferenceError:d3 is not defined ReferenceError:d3 is not defined

命令不起作用的初始菜单项

如何使用ChangeDetectionStrategy.OnPush?

要素存储更改根存储状态

如何将管道异步化添加到不在html模板中的观察对象的Angular ?

MAT-复选框更改事件未在onSubscriberCheck函数中返回选中的值

react 形式之间的循环关系

Angular 信号 - 使用 mutate() 与使用 forEach() react 性

Angular p-triStateCheckbox for each Select 更改不同的 colored颜色

根据最后发出的 observable 创建一个 observable

尽管模型中的变量发生了变化,但Angular 视图没有更新

如何在Angular Material2中获取活动选项卡

Angular 2 - 什么是Root Scope?

错误:formControlName 必须与父 formGroup 指令一起使用.您需要添加一个 formGroup 指令

Angular 2如何让子组件等待异步数据准备好

如何在 Angular 2 的同一个组件中使用多个 ng-content?

为什么 ngOnInit 被调用两次?

如何将 @Input 与使用 ComponentFactoryResolver 创建的组件一起使用?