Присоединяйтесь к 2 наблюдаемым потокам, но у вас есть разные методы доступа - PullRequest
0 голосов
/ 28 февраля 2020

Мне бы очень хотелось, как в определении селектора ngrx, где вы можете подключить несколько наблюдаемых и иметь функцию проекции для возврата чего-либо.

Пример

export const selectCommunityByRouteId = createSelector(
  selectRouteId,
  communitySelectors.selectEntities,
  (id, communities) => {
    if (id) {
      return communities.find(c => c.id === id);
    }
  }
);

^ Существует selectRouteId и communitySelectors.selectEntities, 2 наблюдаемых потока и функция проекции, которая принимает оба входа и возвращает что-то.

Приведенный ниже код находится в моем компоненте. По сути, я делаю, чтобы определить, является ли владелец сообщества тем же, который посещает это сообщество, и если это так, установите элементы меню только для администратора.

Текущий

    this.community$.pipe(
      takeUntil(this.ngDestroyed$),
      switchMap(community => this.store.select(selectProfileByID(community && community.owner_id))),
    ).subscribe(profile => {
      if (profile) {
        const claims = this.oAuthService.getIdentityClaims();
        if (claims) {
          // @ts-ignore
          const sub = claims.sub;
          if (sub === profile.subject_id) {
            this.store.dispatch(setDrawerAdminNavigationItems({items: [
                {title: 'New Forum', route: ['/new/forum']}
              ]}));
          }
        }
      } else {
        this.store.dispatch(setDrawerAdminNavigationItems({items: undefined}));
      }
    });
  }

Однако теперь я на 2 уровня глубже в гнезде и в отношениях Community> Container> Forum, я пытаюсь дать владельцу возможность создать новый форум. Однако для этого мне нужно знать идентификатор Container, который я сейчас просматриваю. У меня есть

    this.container$ = this.store.select(selectContainerByRouteId);

это не проблема. Эта проблема, мне нужно получить доступ к информации, поступающей от этого селектора / наблюдаемого. Итак, в моей подписке мне нужно иметь не только

this.store.select(selectProfileByID(community && community.owner_id)

, но и

this.container$
// or
this.store.select(selectContainerByRouteId)

, поэтому у меня есть что-то вроде

.subscribe([profile, container] => {
// do something with that
});

или, более подробно

Желаемый:

    this.community$.pipe(
      takeUntil(this.ngDestroyed$),
      switchMap(community => this.store.select(selectProfileByID(community && community.owner_id))),
    ).subscribe([profile, container] => {
      if (profile) {
        const CONTAINER_ID_HERE = container.id;
        const claims = this.oAuthService.getIdentityClaims();
        if (claims) {
          // @ts-ignore
          const sub = claims.sub;
          if (sub === profile.subject_id) {
            this.store.dispatch(setDrawerAdminNavigationItems({items: [
                {title: 'New Forum', route: ['/new/forum', CONTAINER_ID_HERE]}
              ]}));
          }
        }
      } else {
        this.store.dispatch(setDrawerAdminNavigationItems({items: undefined}));
      }
    });
  }

Я знаю, что есть forkJoin, но это просто объединяет все потоки в один.

Мне нужен способ получения данных из нескольких потоков и передать его следующей функции. Я полагаю, что ОбъединитьПоследние должны это сделать.

Как должна выглядеть эта функция в сочетании с Последним? Могу ли я все еще использовать switchMap? Могу ли я даже передать его в трубу?

1 Ответ

1 голос
/ 28 февраля 2020

Мне удалось решить это самостоятельно, однако я получаю предупреждение об устаревании о combineLatest. Я обнаружил закрытую проблему GitHub о том, что объединение LatestLatest устарело , а также вопрос Stackoverflow .

В любом случае это мое текущее работающее решение

    this.community$.pipe(
      takeUntil(this.ngDestroyed$),
      switchMap(community => {
        return combineLatest(this.store.select(selectProfileByID(community && community.owner_id)), this.container$);
      }),
    ).subscribe(([profile, container]) => {
      if ((profile) && (container)) {
        const claims = this.oAuthService.getIdentityClaims();
        if (claims) {
          // @ts-ignore
          const sub = claims.sub;
          if (sub === profile.subject_id) {
            this.store.dispatch(setDrawerAdminNavigationItems({
              items: [
                {title: 'New Forum', route: ['/new/forum', container.id]}
              ]
            }));
          }
        }
      } else {
        this.store.dispatch(setDrawerAdminNavigationItems({items: undefined}));
      }
    });
...