NgXs @selector 不支持异步函数

NgXs @selector doesn't support async functions

在我的 NGXS 商店中,我有以下异步选择器

@Selector()
static async mainState(store: IMyStore): Promise<IMyState> {
    return this.getActiveState(store);
}

如果我现在订阅这个选择器

@Select(MyStore.mainState) state$: Observable<IMyState>;

如果我订阅这个流,我会收到承诺而不是 IMyState 对象。所以我必须这样做:

this.state$.subscribe(p => {
    p.then(state => { ... });
});

我可以将 promise 投射到 rxjs 流中,但随后我收到了流

this.state$.subscribe(s => {
    s.subscribe(state => { ... });
});

所以我的问题是,有没有办法在 ngxs 中支持异步选择器?

@Selector 用于“从全局状态容器中切出状态的特定部分”(据我所知,不是在其中调用 async 函数)。

您可以实现您想要做的事情,如下所示:

  • 创建一个新的 @Action 来处理 async 进程。
  • 向您的州添加一个新的 属性 以保持 mainState 值。
  • async 函数获得结果后,用适当的值更新 mainState
  • 为 return mainState 创建一个新的 @Selector 函数。
  • 在您的组件中调度创建的 action
  • 在您的组件中添加 @Select 属性 以从您的州获得 mainState

您的代码可能如下所示:

mystore.state.ts

@Selector()
static mainState(state: IMyStore): IMyState {
    return state.mainState;
}

@Action(LoadMainState)
async loadMainState(ctx: StateContext<IMyStore>) {
  const _activeState = await this.getActiveState(store);
  ctx.patchState({ mainState: _activeState });
}

example.component.ts

@Select(MyStore.mainState) state$: Observable<IMyState>;

ngOnInit(): void {
  this.store.dispatch(new LoadMainState());
}

或者,如果您仍然不想创建笨拙的商店,您可以使用 switchAll() 进行扁平化。这样做可以避免丑陋的订阅内部订阅。

@Select(MyStore.mainState) stateHigherOrder$: Observable<Observable<IMyState>>;
state$!:Observable<IMyState>;    

ngOnInit(): void {
 this.state$ = this.stateHigherOrder$.pipe(switchAll());
}

现在 this.state$ 就是您想要的