嵌套合并组合组合

发布于 2025-02-13 18:16:23 字数 1563 浏览 1 评论 0原文

我正在使用表单tool>功能>查看。换句话说,有工具,工具具有功能,功能具有视图。

在Angular 2(13)中,我正在使用服务来处理HTTP调用以获取数据。当应用启动时,解析器触发了服务的设置工具>数组属性,通过调用服务的settools()方法。此方法应通过获取工具,然后用各个功能填充每个工具来构建工具,这些功能均通过视图填充,全部通过嵌套的HTTP调用每个部分。

我找到了一个实现从rxjs)将其降低到单层。然后,我在服务中实现了以下内容:

setTools(): Observable<Tool[]> {
  return this.getTools().pipe(
    mergeMap(tools =>
      forkJoin<Tool[]>(
        tools.map(tool =>
          this.getFeatures(tool.id).pipe(
            map(features => ({ ...tool, features })
          )
        )
      )
    ),
    tap<Tool[]>(tools => console.log(tools))
  )
}

这可以正常工作。打印工具,每个工具都包含其各自的功能。伟大的!

天真地,我实施了以下内容以实现下一层人群,即视图:

setTools(): Observable<Tool[]> {
  return this.getTools().pipe(
    mergeMap(tools =>
      forkJoin<Tool[]>(
        tools.map(tool =>
          this.getFeatures(tool.id).pipe(
            mergeMap(features =>
              forkJoin<Feature[]>(
                features.map(feature =>
                  this.getViews(feature.id).pipe(
                    map(views => ({ ...feature, views })
                  )
                )
              )
            ),
            map(features => ({ ...tool, features })
          )
        )
      )
    ),
    tap<Tool[]>(tools => console.log(tools))
  )
}

但是,工具不再注销以构成控制。为什么?我在做什么错?另外,如果有另一种实施方法,我将非常感谢输入。仅供参考,我是Web开发的新手。

I'm working with data of the form tool > feature > view. In other words, there are tools, a tool has features, a feature has views.

In Angular 2 (13), I'm using a service to handle http calls to fetch data. When the app starts, a resolver triggers the setting of the service's tools array property by calling the service's setTools() method. This method should build tools by fetching the tools, then populating each tool with features, which are each populated with views, all via nested http calls for each part.

I found an implementation using a combination of mergeMap and forkJoin (from rxjs) that achieves this down a single layer. I then implemented the following in the service:

setTools(): Observable<Tool[]> {
  return this.getTools().pipe(
    mergeMap(tools =>
      forkJoin<Tool[]>(
        tools.map(tool =>
          this.getFeatures(tool.id).pipe(
            map(features => ({ ...tool, features })
          )
        )
      )
    ),
    tap<Tool[]>(tools => console.log(tools))
  )
}

This works correctly. Tools are printed out, each containing its respective features. Great!

Naively, I implemented the following to achieve the next layer of population, i.e. views:

setTools(): Observable<Tool[]> {
  return this.getTools().pipe(
    mergeMap(tools =>
      forkJoin<Tool[]>(
        tools.map(tool =>
          this.getFeatures(tool.id).pipe(
            mergeMap(features =>
              forkJoin<Feature[]>(
                features.map(feature =>
                  this.getViews(feature.id).pipe(
                    map(views => ({ ...feature, views })
                  )
                )
              )
            ),
            map(features => ({ ...tool, features })
          )
        )
      )
    ),
    tap<Tool[]>(tools => console.log(tools))
  )
}

However, tools no longer log out to console. Why? What am I doing wrong? Also, if there is another way to implement this, I'll greatly appreciate the input. FYI, I'm quite new to web development.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一身仙ぐ女味 2025-02-20 18:16:23

没有更多的代码/类型,我无法让您的榜样工作,因此我稍微更改了该方法,并且可能无法完全回答问题。将Mergemap与MergeAll和阵列一起提供嵌套结构。

  setTools() {
    return this.getTools().pipe(
      mergeAll(),
      mergeMap(tool =>
        this.getFeatures(tool.id).pipe(
          mergeAll(),
          mergeMap(feature=>
             this.getViews(feature.id).pipe(
                 map((views) => ({...feature, views }))
             )
          ),
          toArray(),
          map((features)=>({...tool, features}))
        )
      ),
      toArray(),
    );
  }

请参阅Stackblitz: https://stackblitz.com/edit/angular-ivy-ee1myv?file=src/app/app/app/app.component.ts

I could not get your example to work without more code/types, so I've changed the approach slightly and might not answer the question completely. Using mergeMap with mergeAll and to Array gives the nested structure.

  setTools() {
    return this.getTools().pipe(
      mergeAll(),
      mergeMap(tool =>
        this.getFeatures(tool.id).pipe(
          mergeAll(),
          mergeMap(feature=>
             this.getViews(feature.id).pipe(
                 map((views) => ({...feature, views }))
             )
          ),
          toArray(),
          map((features)=>({...tool, features}))
        )
      ),
      toArray(),
    );
  }

See stackblitz: https://stackblitz.com/edit/angular-ivy-ee1myv?file=src/app/app.component.ts

痕至 2025-02-20 18:16:23

我只是将您的代码分为几个单独的功能。它在简约的安全带上对我来说很好。基本上没有变化...

embellishFeature(feature){
  return this.getViews(feature.id).pipe(
    map(views => ({...feature, views}))
  );
}

embellishFeatures(features){
  return forkJoin(features.map(v => this.embellishFeature(v)));
}

embellishTool(tool){
  return this.getFeatures(tool.id).pipe(
    mergeMap(v => this.embellishFeatures(v)),
    map(features => ({...tool, features}))
  );
}

embellishTools(tools){
  return forkJoin(tools.map(v => this.embellishTool(v)));
}

setTools(): Observable<Tool[]> {
  return this.getTools().pipe(
    mergeMap(v => this.embellishTools(v)),
    tap(tools => console.log(tools))
  );
}

I've just separated out your code into a few separate functions. It runs just fine for me on a minimalist harness. Basically no changes...

embellishFeature(feature){
  return this.getViews(feature.id).pipe(
    map(views => ({...feature, views}))
  );
}

embellishFeatures(features){
  return forkJoin(features.map(v => this.embellishFeature(v)));
}

embellishTool(tool){
  return this.getFeatures(tool.id).pipe(
    mergeMap(v => this.embellishFeatures(v)),
    map(features => ({...tool, features}))
  );
}

embellishTools(tools){
  return forkJoin(tools.map(v => this.embellishTool(v)));
}

setTools(): Observable<Tool[]> {
  return this.getTools().pipe(
    mergeMap(v => this.embellishTools(v)),
    tap(tools => console.log(tools))
  );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文