微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

结合 MemoizedSelector 和普通选择器组合 ngrx 选择器

如何解决结合 MemoizedSelector 和普通选择器组合 ngrx 选择器

我有一个大型项目正在慢慢迁移到新的 ngrx 语法。我们有很多选择器都是像这样的普通函数

export function appDetailsSelector(state$: Observable<AppState>): Observable<AppDetails> {
    return state$.pipe(map((appState: AppState) => appState.appDetails));
}

使用 createSelector 编写新的选择器:

export const selectUserConfig: MemoizedSelector<AppState,UserConfig> = createSelector(
  selectUserData,(userData: UserData) => userData.config,);

这两个都使用相同的状态形状,但是我如何组合以创建一个将这两个与 createSelector 组合在一起的新选择器?

我知道我可以在组件代码中使用管道来做到这一点:

combineLatest([
  this.store.pipe(appDetailsSelector),this.store.select(selectUserConfig),],(appDetails,userConfig) => ...projector fn code...);

但这不是可重用的,我需要用 createSelector 完成以避免在多个组件中重复此操作。如果 appDetailsSelector 是用 createSelector 创建的,它看起来像这样:

export const getUserBookmarks = createSelector(
  appDetailsSelector,selectUserConfig,(appDetails: AppDetails,userConfig: UserConfig) => appDetails.useBookmarks ? userConfig.bookmarks : []
);

但是这个Argument of type 'MemoizedSelector<AppState,UserConfig,DefaultProjectorFn<UserConfig>>' is not assignable to parameter of type 'SelectorWithProps<Observable<AppState>,unkNown,UserConfig>'.   Types of parameters 'state' and 'state' are incompatible.     Type 'Observable<AppState>' is missing the following properties from type 'AppState'...

我可以看到旧式选择器采用 Observable<AppState>,而新式选择器采用 AppState;如何弥合这一差距并结合这两个选择器?

解决方法

您可以使用类型转换

export const getUserBookmarks = createSelector(
  appDetailsSelector as MemoizedSelector<AppState,UserConfig,DefaultProjectorFn<UserConfig>>,selectUserConfig as MemoizedSelector<AppState,(appDetails: AppDetails,userConfig: UserConfig) => appDetails.useBookmarks ? userConfig.bookmarks : []
);

Typecasting 会将类型设置为相同的类型

,

无法将 Observable 选择器与新的 createSelector 语法一起使用。 Observable 选择器对 observable 进行操作,而函数选择器直接对 observable 中包含的数据进行操作;没有开箱即用的方法可以让它们协同工作。

注意,observable 选择器实际上是变相的函数选择器;如果您需要维护经典选择器,只需将有状态逻辑移出到函数选择器中,并在每个上下文中使用正确的选择器。

export const appDetailsSelector = (state: AppState) => state.appDetails;

export const appDetailsObservableSelector = (state$: Observable<AppState>) =>
  state$.pipe(map(appDetailsSelector));

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。