Я не могу разобрать данные и преобразовать в плоский список - PullRequest
1 голос
/ 12 апреля 2019

Используя 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[]> Это первый набор данных.

вид-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"
  },
]

Может ли кто-нибудь помочь достичь этого?

1 Ответ

0 голосов
/ 12 апреля 2019

Вот ваш упрощенный пример. Он использует насмешки для имитации каталогов и выборки товаров.

Я пытался добавить столько комментариев, сколько нужно.

Общая идея заключается в следующем:

  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));
}
<script src="https://unpkg.com/rxjs@6.4.0/bundles/rxjs.umd.min.js"></script>

Надеюсь, это поможет

...