在Subscribe方法中构建Parent Child对象

时间:2019-02-04 06:26:20

标签: angular typescript angular5

我有一个Angular组件,它订阅了由Angular服务返回的可观察对象。

组件: help.component.ts

int rndNum = rnd.nextInt(Names.lastName.length);

import { WikiService } from '../../../services/wiki.service'; import { WikiTree } from '../../../interfaces/WikiTree'; export class HelpComponent implements OnInit { wikiTree$: Observable<WikiTree> wikiChildTree$: Observable<WikiTree> public infoCards: Array<Object>; constructor(private wikiService: WikiService) {} ngOnInit() { this.wikiTree$ = this.wikiService.GetWikiHierarchy(); this.wikiTree$.subscribe((data)=>{ const newInfoCards = data.page.results.map(result => ( { "image": "", "title": result.title, "titleLink": "/page/wiki/"+ result.id, "children": [] /*TODO: Populate this array with a Service call based on result.id*/ })) this.infoCards = [...this.infoCards,...newInfoCards] }, (err) => { console.log(err); } ); } 的Observable具有转换为TypeScript的以下JSON:

wikiTree$

TypeScript:WikiTree.ts

{
    "page": {
        "results": [
            {
                "id": "123456789",
                "type": "page",
                "status": "current",
                "title": "Start here",
                "extensions": {
                    "position": 0
                },
                "_links": {
                    "webui": "/display/MYSPACE/Start+here",
                    "edit": "/pages/resumedraft.action?draftId=123456789",
                    "tinyui": "/x/BQD2Mw",
                    "self": "https://wiki.abc.com/rest/api/content/123456789"
                },
                "_expandable": {
                    "container": "/rest/api/space/MYSPACE",
                    "metadata": "",
                    "operations": "",
                    "children": "/rest/api/content/123456789/child",
                    "restrictions": "/rest/api/content/123456789/restriction/byOperation",
                    "history": "/rest/api/content/123456789/history",
                    "ancestors": "",
                    "body": "",
                    "version": "",
                    "descendants": "/rest/api/content/123456789/descendant",
                    "space": "/rest/api/space/MYSPACE"
                }
            },
            {
                "id": "567890123",
                "type": "page",
                "status": "current",
                "title": "FAQ",
                "extensions": {
                    "position": 1
                },
                "_links": {
                    "webui": "/display/MYSPACE/FAQ",
                    "edit": "/pages/resumedraft.action?draftId=567890123",
                    "tinyui": "/x/HQD2Mw",
                    "self": "https://wiki.abc.com/rest/api/content/567890123"
                },
                "_expandable": {
                    "container": "/rest/api/space/MYSPACE",
                    "metadata": "",
                    "operations": "",
                    "children": "/rest/api/content/567890123/child",
                    "restrictions": "/rest/api/content/567890123/restriction/byOperation",
                    "history": "/rest/api/content/567890123/history",
                    "ancestors": "",
                    "body": "",
                    "version": "",
                    "descendants": "/rest/api/content/567890123/descendant",
                    "space": "/rest/api/space/MYSPACE"
                }
            }
        ],
        "start": 0,
        "limit": 25,
        "size": 2,
        "_links": {
            "self": "https://wiki.abc.com/rest/api/content/998877665/child/page"
        }
    },
    "_links": {
        "base": "https://wiki.abc.com",
        "context": "",
        "self": "https://wiki.abc.com/rest/api/content/998877665/child"
    },
    "_expandable": {
        "attachment": "/rest/api/content/998877665/child/attachment",
        "comment": "/rest/api/content/998877665/child/comment"
    }
}

我想根据对服务的父export interface WikiTree { page: Page; _links: Links; _expandable: Expandable; } export interface Page { results?: (ResultsEntity)[] | null; start: number; limit: number; size: number; _links: Links1; } export interface ResultsEntity { id: string; type: string; status: string; title: string; extensions: Extensions; _links: Links2; _expandable: Expandable1; } export interface Extensions { position: number; } export interface Links2 { webui: string; edit: string; tinyui: string; self: string; } export interface Expandable1 { container: string; metadata: string; operations: string; children: string; restrictions: string; history: string; ancestors: string; body: string; version: string; descendants: string; space: string; } export interface Links1 { self: string; } export interface Links { base: string; context: string; self: string; } export interface Expandable { attachment: string; comment: string; } 的调用来填充children数组

例如:调用将是Wiki Service中的一个函数,该函数返回一个可观察的对象。

result.id

根据可观察到的this.wikiChildTree$ = this.wikiService.GetWikiHierarchy(result.id); 返回的数据,我想创建一个wikiChildTree$title对象的数组。因此,link对象数组将反映这样的JSON对象:

infoCards

这就像进行父子异步调用一样,以获取子数据。

我已经阅读了有关forkjoin和mergemap的信息,但不确定此处的实现。我怎么做?

2 个答案:

答案 0 :(得分:1)

因此,基本上,您应该能够像这样:

ngOnInit() {
       this.wikiTree$ = this.wikiService.GetWikiHierarchy().pipe(
          switchMap(data => 
             forkJoin(data.page.results.map(result => this.wikiService.GetWikiHierarchy(result.id))).pipe(
                map(children => ({data, children}))
             )
          )
       ).subscribe(({data, children}) => {
            const newInfoCards = data.page.results.map((result, i) => (
            {
              "image": "",
              "title": result.title,
              "titleLink": "/page/wiki/"+ result.id,
              "children": children[i]
            }))
            this.infoCards = [...this.infoCards,...newInfoCards]
          },
          (err) => {
            console.log(err);
          }
       );
}

说明:

  1. 您加载 this.wikiService.GetWikiHierarchy();
  2. 您使用 forkJoin同时为每个结果加载所有 this.wikiService.GetWikiHierarchy(result.id)
  3. 您将两个位置的加载数据映射到对象 {data,children} 中,其中 data -第一次调用的结果 children -的结果第二个 forkJoin(子代数组或儿童[] [])
  4. 此后,您需要将 data.page.results 子级(数组的数组)关联。 希望有帮助。

答案 1 :(得分:0)

将返回数据添加到Amir的答案中,以消除错误。 map函数需要返回WikiTree类型的可观察对象。

ngOnInit() {
       this.wikiTree$ = this.wikiService.GetWikiHierarchy().pipe(
          switchMap(data => 
             forkJoin(data.page.results.map(result => this.wikiService.GetWikiHierarchy(result.id))).pipe(
                map(children => ({data, children}))
             )
          )
       ).subscribe((data, children) => {
            const newInfoCards = data.page.results.map((result, i) => (
            {
              "image": "",
              "title": result.title,
              "titleLink": "/page/wiki/"+ result.id,
              "children": children[i]
            }))
            this.infoCards = [...this.infoCards,...newInfoCards]
            return data
          },
          (err) => {
            console.log(err);
          }
       );
}