Aurelia管道步骤中使用@connectTo装饰器时State始终未定义
你猜的没错,问题的核心确实是AuthorizeStep作为管道步骤,不会自动触发Aurelia的bind生命周期钩子,而@connectTo装饰器正是依赖这个生命周期来完成与Store的状态绑定的——没有bind的触发,状态就不会被映射到this.state属性上。
下面给你两种靠谱的解决方案,推荐第一种更适配管道场景的实现:
方案一:直接注入Store获取状态(推荐)
管道步骤本质不是视图模型,用@connectTo本来就属于“错配”场景。更直接的方式是注入Store实例,手动获取当前状态快照:
import { autoinject } from 'aurelia-framework'; import { Store } from 'aurelia-store'; import { State } from '../your-state-path'; // 替换成你的State类型路径 @autoinject() export class AuthorizeStep { constructor(private store: Store<State>) {} run(navigationInstruction, next) { // 获取当前状态的最新快照 const currentState = this.store.state.getValue(); const requiresAdmin = navigationInstruction.getAllInstructions() .some(x => x.config.isAdmin); if (requiresAdmin && !currentState.user.isAdmin) { return next.cancel(); } return next(); } }
这种方式不需要依赖视图生命周期,直接通过Store的state Observable获取当前状态,更符合管道步骤的使用场景。
方案二:手动触发bind生命周期(兼容@connectTo)
如果你一定要保留@connectTo的写法,可以手动实现bind方法并在run中触发,强制完成状态绑定:
import { autoinject } from 'aurelia-framework'; import { connectTo, Store } from 'aurelia-store'; import { State } from '../your-state-path'; @autoinject() @connectTo() export class AuthorizeStep { state: State; constructor(private store: Store<State>) {} // 手动实现bind钩子,触发@connectTo的状态绑定逻辑 private bind(): void { if (!this.state) { // 订阅一次状态更新,将最新状态赋值给this.state this.store.state.subscribe(state => this.state = state); } } run(navigationInstruction, next) { // 先确保状态绑定完成 this.bind(); const requiresAdmin = navigationInstruction.getAllInstructions() .some(x => x.config.isAdmin); // 这里加个可选链避免状态未初始化时报错 if (requiresAdmin && !this.state?.user.isAdmin) { return next.cancel(); } return next(); } }
为什么会出现这个问题?
再补充下原理帮你理解:@connectTo装饰器是为Aurelia视图模型设计的,它会在视图模型的bind生命周期阶段自动完成Store状态与类属性的映射。但管道步骤(比如AuthorizeStep)是Aurelia导航系统的扩展类,框架不会为它触发视图模型特有的生命周期钩子,所以@connectTo的绑定逻辑根本没机会执行,自然this.state就是undefined。
内容的提问来源于stack exchange,提问作者ViqMontana
相关产品推荐
相关产品推荐

