Вернуть объединенный объект, состоящий из двух разных Observable с зависимостями с RxJS - PullRequest
0 голосов
/ 03 марта 2019

Я собираюсь объяснить контекст, который у меня есть, прежде чем объяснить проблему проектирования службы с Angular и RxJS.

У меня есть один объект с этой моделью:

{
  id: string;
  title: string;
  items: number[];
}

Я получаюкаждый объект этого типа (называемый «элемент») - от GET /element/:id

Каждый элемент имеет items: number[], который содержит массив чисел, и у каждого числа есть URL, поэтому я делаю новый GET /element/:id/:itemNumber для каждогономер и вернуть детали детали.Модель детализации выглядит следующим образом:

{
  idItem: string;
  title: string;
}

Так что в моем сервисе я хочу предоставить компонентам метод, который будет возвращать Observable, он получит массив объектов, где у каждого объекта есть элементмодель с одним дополнительным свойством, которое будет массивом ее подробных элементов.Итак, я собираюсь показать, что у меня есть:

Служба:

getElement(id: string): any {
  return this.http.get<Element>(this.basePath + `/element/${id}`).pipe(
    map(element => this.getAllItemsDetail(element))
}

getAllItemsDetail(element: Element): any {
  return of(...element.items).pipe(
    map(val => this.getItemDetail(element.id, val)),
    concatAll()
  );
}

Моя проблема в том, что я не понимаю, как я могу, в RxJS, после map(element => this.getAllItemsDetail(element)) в методе getElement объедините возвращаемый им массив элементов и предыдущий элемент, который у меня есть, перед картой, содержащей объект элемента.Мне нужно добавить «что-нибудь» после этой карты, чтобы вычислить Object.Assign для объединения обоих объектов.

EDIT

С ответом @ chiril.sarajiu,он дает мне более чем одну подсказку, с помощью switchMap я могу отобразить наблюдаемое (map используется для объектов, "выполнить вычисление с объектом результата").Так что мой код, это не самая красивая версия, которую я знаю ..., я попробую, но она работает.Таким образом, окончательный код выглядит следующим образом:

getElement(id: string): any {
  return this.http.get<Element>(this.basePath + `/element/${id}`).pipe(
    switchMap(element => this.getAllItemsDetail(element)),
    map(result => { return Object.assign({}, result.element, {itemsDetail: result.items})})
  );
}

getAllItemsDetail(element: Element): any {
  const results$ = [];

  for (let i = 0; i < element.items.length; i++) {
    results$.push(this.getItemDetail(element.id, element.items[i]));
  }

  return zip(...results$).pipe(
    map(items => { return Object.assign({}, { element, items })})
  );
}

Помните, что zip не будет выдавать значения, если результаты $ пустые, в этом случае вы можете добавить (не определено) к массиву результатов $и после учтите, что предметы будут [undefined]

1 Ответ

0 голосов
/ 03 марта 2019

Чтобы отобразить другую наблюдаемую, вы должны использовать switchMap функцию вместо map Так

getElement(id: string): any {
  return this.http.get<Element>(this.basePath + `/element/${id}`).pipe(
    switchMap(element => this.getAllItemsDetail(element))
}

ОБНОВЛЕНИЕ

Рассмотрите эту среднюю статью

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...