如何访问 ngrx/effects 中的解析器数据? (v7)

How to access Resolver Data in ngrx/effects? (v7)

我在组件中调用了 api,这很耗时 ,所以我已经实现了 resolver。我希望 解析器数据出现在商店 中以供以后使用。我已经实现了 ngrx/store、ngrx/effects 和 ngrx/router-store.

组件中的当前状态

期望状态

为了保存解析器数据,我需要访问效果中的解析器数据。所以我可以简单地在组件中发送动作并订阅状态。

问题

我总是在 CustomSerializer 的 "data" 中变空 {}


如何访问特效中的解析器数据?提前致谢。


代码

减速器/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);

您的效果不能(也不应该)访问解析器。

解析器应该检查存储中是否有东西,如果没有,它应该调度一个操作来检索数据。

Todd Motto 在 https://toddmotto.com/preloading-ngrx-store-route-guards 上用一些很好的例子很好地解释了这一点。

以下有效,致谢:@timdeschryver

  • 调用解析器数据而不是效果,解析器需要调度操作。
  • 该组件将简单地订阅商店并获取更新

解析器

@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;
          });