Выберите один наблюдаемый объект на основе условия

#angular #rxjs #rxjs5

#angular #rxjs #rxjs5

Вопрос:

Я пишу приложение ng2 и использую службу состояния приложения на основе поведенческих объектов, которые предоставляют наблюдаемые объекты. Для большинства вариантов использования я хочу использовать observable A для поиска вложенного объекта. Я обнаружил странный случай, когда наблюдаемый объект A не будет иметь этих данных, но он находится в наблюдаемом объекте B. Оба наблюдаемых объекта A и B доступны из моей службы состояния приложения.

Прямо сейчас в моем компоненте это выглядит так

   sharedState: Observable<any>;

  constructor(private appStateService: AppStateService) {
    this.sharedState = appStateService.shared$;
  }
 

Тогда, на мой взгляд :

 <div>{{ (sharedState | async)?.loadedAccountDetails?.accountId }}</div>
 

В качестве одного примера. Я полагаю, что мне нужно сделать сейчас в компоненте:

  1. Подпишитесь на Observable A и проверьте, есть ли у него мои loadedAccountDetails, идентификатор учетной записи и т. Д
  2. Если A не имеет этого значения, тогда используйте B

То, что я надеялся сделать и в компоненте, заключалось в том, чтобы выставлять / иметь только одну переменную экземпляра, которая является наблюдаемой, чтобы я мог сохранить свой view / html таким же.

Даже если вы не знакомы с Angular 2, я могу поработать над этим, но мне нужна помощь в понимании того, как практически реализовать оператор if с наблюдаемыми.

Ответ №1:

Попробуйте это:

 Observable
  // When any of the inner observables emit, supply latest from all
  .combineLatest(observableA, observableB)
  // Emit either result
  .map(([resultA, resultB]) => resultA || resultB)
  // Test it
  .subscribe(console.info)
 

Просто убедитесь observableA/B , что он ничего не выдает, если не находит то, что вы ищете (используйте .filter(Boolean) , например).

Комментарии:

1. итак, когда вы сопоставляете (просто пытаясь понять ваши комментарии), вы подписываетесь на наблюдаемые, чтобы получить их значения… Это то, что такое ResultA / b ?

2. @Барри Да, resultA/B это то, что observableA/B излучает. Смотрите примеры в документах: combineLatest

3. итак, как только я создаю свою карту, я «знаю», какой наблюдаемый объект я хочу выбрать и т. Д. Можете ли вы подробнее объяснить take(1) ? Я думаю, что внутри логики карты я могу установить для моей открытой переменной экземпляра правильное наблюдаемое значение и быть полным, но нужно ли мне что-нибудь делать, чтобы остановить эту цепочку?

4. map просто преобразует значения на основе того, что вы ему передаете. Это не подписка, а добавление еще одного этапа к производственной линии — подписка запускает производственную линию.

5. @Sasca Я не думаю, что это правильно. Вам нужно либо принять массив из двух элементов, map либо предоставить функцию сопоставления с двумя аргументами в качестве третьего аргумента combineLatest . Функция, передаваемая map только когда-либо, принимает только один аргумент.

Ответ №2:

Вы также можете рассмотреть amb , который использует тот наблюдаемый объект, который сначала выдает значение, а затем отписывается от второго:

 Observable.amb(
    firstSource.filter(x => x.loadedAccountDetails),
    secondSource.filter(x => x.loadedAccountDetails)
)
.subscribe(x => { })