【问题标题】:I can not parse the data and convert to a flat list我无法解析数据并转换为平面列表
【发布时间】:2019-09-02 19:52:03
【问题描述】:

使用ngrx,我从存储中获得了两个数据集。

  private getCatalog() {
    this.catalogStore.select(CatalogStoreSelectors.selectAllCatalogsLoadSuccess)
      .pipe(
        takeWhile(() => this.alive),
        take(1),
        filter(loadSuccess => !loadSuccess),
        tap(() => this.catalogStore.dispatch(new CatalogStoreActions.LoadAllAction())),
      ).subscribe();

    this.catalogs$ = this.catalogStore.select(CatalogStoreSelectors.selectAllCatalogs);
  }

catalog$ 将是 Observable<ViewCatalog[]> 这是第一个数据集。

view-catalog.ts

export declare class ViewCatalog {
    code: string;
    title: string;
    lastModified: string;
}

对于每个catalog,您可以通过catalog code 请求其项目

  private getCatalogItems(catalogCode: string) {
    this.catalogStore.dispatch(new CatalogStoreActions.GetCatalogItems({catalogCode: catalogCode}));

    this.catalogItemsStore.select(CatalogItemStoreSelector.selectLoadingByCatalogSuccess)
      .pipe(
        takeWhile(() => this.alive),
        take(1),
        filter(loadSuccess => !loadSuccess),
        tap(() => this.catalogItemsStore.dispatch(new CatalogItemStoreAction.LoadByCatalog({catalogCode: catalogCode}))),
      ).subscribe();

    this.catalogItems$ =  this.catalogItemsStore.select(CatalogItemStoreSelector.selectByCatalogCode(catalogCode));
  }

这是第二个数据集。

public catalogItems$: Observable<CatalogItem[]>;

CatalogItem.ts

export class CatalogItem {
  constructor(public code: string,
              public catalogCode: string,
              public title: string,
              public data: object) {
  }
}

我需要将所有这些数据合并到一个常见的平面列表中,如下所示:

[
  catalog: {
    code: "Code 1",
    title: "Catalog title 1",
    lastModifie": "",
    parent: null,
    hasChildren: true
  }
  catalog-item: {
    code: "CatalogItem 1",
    catalogCode: "Code 1",
    parent: "Code 1",
    hasChildren: false,
    title: "CatalogItem title 1"
  },
  catalog-item: {
    code: "CatalogItem 2",
    catalogCode: "Code 1",
    parent: "Code 1",
    hasChildren: false,
    title: "CatalogItem title 2"
  },
  catalog: {
    code: "Code 2",
    title: "Catalog title 2",
    lastModifie": "",
    parent: null,
    hasChildren: true
  },
  catalog-item: {
    code: "CatalogItem 1",
    catalogCode: "Code 2",
    parent: "Code 2",
    hasChildren: false,
    title: "CatalogItem title 1"
  },
  catalog-item: {
    code: "CatalogItem 2",
    catalogCode: "Code 2",
    parent: "Code 2",
    hasChildren: false,
    title: "CatalogItem title 2"
  },
]

有人可以帮助实现这一目标吗?

【问题讨论】:

标签: angular typescript rxjs observable


【解决方案1】:

这是您的一个简化示例。它使用模拟来模拟目录和项目获取。

我已尝试根据需要添加尽可能多的 cmets。

总体思路是:

  1. 获取所有目录

  2. 为每个目录获取其项目,然后将它们放入包含目录的数组中

  3. 然后将所有这些数组合并为一个

const { of, combineLatest } = rxjs;
const { delay, switchMap, map } = rxjs.operators;

// 1. fetch all catalogues
// Observable<ViewCatalog[]>
getCatalogues().pipe(
  // chain to fetching items Observables
  switchMap(catalogues => {
    // 2. turn _each catalogue entry_ into
    // [ ViewCatalog, CatalogItem, CatalogItem ... ]
    // results: Observable<(ViewCatalog|CatalogItem)[]>[]
    const results = catalogues.map(
      cat => getItemsForCatalogue(cat.code).pipe(
        // now, merge the ViewCatalog entry
        // with the CatalogItem[] items for this catalogue
        map(items => [cat, ...items])
      )
    ); 

    // 3. use combineLatest to take the latest emissions from the store
    return combineLatest(
      results,
      // and project _each result_ into one array
      // `catsWithItems` here is of type `(ViewCatalog|CatalogItem)[][]`
      (...catsWithItems) => [].concat(...catsWithItems)
    );
  })
)
.subscribe(console.log)


// MOCKS
// getCatalogues(): Observable<ViewCatalog[]>
function getCatalogues(){
  const catalogues =
    [ { code: 1, name: 'cat-1' }
    , { code: 3, name: 'cat-3' }
    , { code: 5, name: 'cat-5' }
    ]

  return of(catalogues).pipe(delay(300));
}

// getItemsForCatalogue(catalogCode: number): Observable<CatalogItem[]>
function getItemsForCatalogue(catalogCode){
  const catalogueItems =
    [ { catalogCode: 1, name: 'item-1' }
    , { catalogCode: 1, name: 'item-2' }
    , { catalogCode: 5, name: 'item-3' }
    ]

  const items = catalogueItems.filter(
      item => item.catalogCode == catalogCode
    );

  return of(items).pipe(delay(300));
}
&lt;script src="https://unpkg.com/rxjs@6.4.0/bundles/rxjs.umd.min.js"&gt;&lt;/script&gt;

希望对你有帮助

【讨论】:

    猜你喜欢
    • 2010-12-16
    • 2021-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-25
    • 1970-01-01
    • 1970-01-01
    • 2020-01-26
    相关资源
    最近更新 更多