Как получить доступ к данным Resolver в ngrx / Effects?(V7) - PullRequest
0 голосов
/ 15 октября 2018

У меня вызовы API в компоненте, который занимает время , поэтому я реализовал resolver .Я хочу, чтобы данные резолвера присутствовали в магазине для дальнейшего использования.Я реализовал ngrx / store, ngrx / Effects и ngrx / router-store.

Текущее состояние в компоненте

  • получение данных непосредственно из данных преобразователя в компоненте(маршрут имеет тип ActivatedRoute) comp

Желаемое состояние

Чтобы сохранить данные резольвера в хранилище, мне нужноДоступ к данным решателя в эффектах.Так что я могу просто отправить действие в компоненте и подписать состояние.

  • диспетчерское действие (LoadSubTopicDetails) в компоненте
  • Effects будет прослушивать действие и получать доступ к тем же данным resolver.в эффектах

Проблема

Я всегда получаю пустое значение {} в «данных» в CustomSerializer.

  • используя resolver в app-routing.module.ts routing-module

  • консольный вывод при маршрутизации в SubTopic /: subTopicId console


Как получить доступ к данным распознавателя в эффектах?Заранее спасибо.


Код

Редукторы / index.ts (CustomSerializer)

export interface RouterStateUrl {
  url: string;
  queryParams: Params;
  params: Params;
  data: any;
}

export const reducers: ActionReducerMap<State> = {
  routerReducer: fromRouter.routerReducer
};

@Injectable()
export class CustomSerializer implements fromRouter.RouterStateSerializer<RouterStateUrl> {
  serialize(routerState: RouterStateSnapshot): RouterStateUrl {
    let route = routerState.root;
    while (route.firstChild) {
      route = route.firstChild;
    }

    const { url, root: { queryParams } } = routerState;
    const { params, data } = route;
    console.log('routerData in CustomSerializer', { url, queryParams, params, data });

    return { url, queryParams, params, data };
  }
}

Редукторы / router.selector.ts

export const getRouterState = createFeatureSelector< RouterReducerState<RouterStateUrl> >('routerReducer');

component.ts

// current state of component
this.subTopicDetails = this.route.snapshot.data['content'];

// new way (desired state), getting "resolver data" from store
this.store.dispatch(new fromCourse.LoadSubTopicDetails);
this.store.select(getSubTopicDetails)
          .subscribe(data => this.subTopicDetails = data);

Ответы [ 2 ]

0 голосов
/ 20 октября 2018

Сработали следующие кредиты: @ timdeschryver

  • Вместо эффектов, вызывающих resolver-data, resolver должен отправить действие.
  • компонент просто подпишется на хранилище иполучать обновления

resolver-effects

распознаватель

@Injectable()
export class SubTopicDetailsResolver implements Resolve<any> {
    constructor(private store: Store<State>) {}

    resolve(route: ActivatedRouteSnapshot) {
        this.store.dispatch(new fromCourse.LoadSubTopicDetails);
    }
}

эффекты

  @Effect()
  loadSubTopicDetails$ = this.actions$.pipe(
    ofType<fromCourse.LoadSubTopicDetails>(CourseActionTypes.LOAD_SUBTOPIC_DETAILS),
    withLatestFrom(
      this.store.select(getRouterState),
      (action, router) => router.state.params.subTopicId
    ),
    switchMap(subtopicId => {
      return this.service.getSubTopicDetails(subtopicId).pipe(
        map(data => new fromCourse.LoadSubTopicDetailsSuccess(data))
      );
    })
  );

компонент

this.store.select(getSubTopicDetails)
          .subscribe(data => {
            this.subTopicDetails = data;
          });
0 голосов
/ 20 октября 2018

Ваши эффекты не могут (и не должны) получать доступ к распознавателям.

Средство распознавания должно проверять, есть ли что-то в хранилище, а если нет, отправлять действие для извлеченияdata.

Тодд Мотто очень хорошо объясняет это несколькими хорошими примерами на https://toddmotto.com/preloading-ngrx-store-route-guards.

...