0

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

组件中的当前状态

  • 直接从组件中的解析器数据获取数据(路由类型为 ActivatedRoute) 补偿

期望的状态

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

  • 组件中的调度操作(LoadSubTopicDetails)
  • effects 将监听 action 并在 effects 中访问相同的解析器数据

问题

我总是{}在 CustomSerializer 的“数据”中变空。

  • 在 app-routing.module.ts 中使用解析器 路由模块

  • 路由到 SubTopic/:subTopicId 时的控制台输出 安慰


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


代码

reducers / 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');

组件.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);

4

2 回答 2

3

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

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

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

于 2018-10-20T15:43:26.273 回答
1

以下工作,学分:@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;
          });

于 2018-10-20T18:16:13.293 回答