NGXS Selectors异常:逻辑一致的方法返回结果不同及实例调用疑问
问题代码
@Selector() static broken(state: AuthStateModel): string | null { return state.token; } @Selector() static token(state: AuthStateModel): string | null { return state.token; } isAuth$: Observable<boolean> = this.store.selectOnce(state => state.auth.token); isTest$: Observable<boolean> = this.store.selectOnce(state => state.auth.broken); this.isAuth$.subscribe(x => { console.log(x); }); this.isTest$.subscribe(x => { console.log(x); });
补充实例Selector代码:
@Selector() isAuthenticated(state: AuthStateModel): boolean { if(state.token !=null) return this.tokenService.isValidToken(state.token); return false; }
问题分析与解决方案
1. 静态Selector调用错误
你通过state.auth.broken的方式调用静态Selector是错误的。NGXS中,state.auth.token能拿到值是因为token是AuthStateModel里的原始状态属性,而broken是你定义的静态Selector,不能直接通过状态对象属性访问。
正确调用静态Selector的方式:
- 直接传入Selector方法:
// 修正类型为string | null,和Selector返回值匹配 isTest$: Observable<string | null> = this.store.selectOnce(AuthState.broken);
- 用
createSelector组合(适合复杂场景):
const selectBrokenToken = createSelector([AuthState], AuthState.broken); isTest$: Observable<string | null> = this.store.selectOnce(selectBrokenToken);
2. 实例Selector的正确写法
实例Selector不能直接使用this.tokenService这类类成员依赖,因为NGXS的Selector是纯函数,会被缓存,实例化依赖会导致缓存失效或运行异常。推荐两种修正方式:
方式一:注入状态容器
@Selector({ injectContainer: true }) isAuthenticated(state: AuthStateModel, container: AuthState): boolean { if(state.token != null) return container.tokenService.isValidToken(state.token); return false; }
注:需确保AuthState类已注入TokenService。
方式二:工厂函数创建Selector(推荐)
export const isAuthenticated = createSelector( [AuthState], (state: AuthStateModel) => { const tokenService = inject(TokenService); return state.token ? tokenService.isValidToken(state.token) : false; } );
组件中调用:
isAuthenticated$: Observable<boolean> = this.store.selectOnce(isAuthenticated);
内容的提问来源于stack exchange,提问作者Sekula
相关产品推荐
相关产品推荐

