Angular中路由加载的组件订阅服务时始终获取初始值而非当前值该如何解决?
Angular中路由加载的组件订阅服务时始终获取初始值而非当前值该如何解决?
嗨,我来帮你排查这个问题~ 其实问题的根源就在你的MenuComponent的组件配置里!
你看,在MenuComponent的@Component元数据中,你把NavigationService加到了providers数组里:
providers: [MenuDatabase, NavigationService],
但你的NavigationService已经通过@Injectable({ providedIn: 'root' })声明成了全局单例服务。Angular的依赖注入规则是:如果组件自己的providers里声明了某个服务,它会创建一个组件专属的新实例,而不是复用根注入器的单例。
这就导致了一个尴尬的情况:
MenuComponent里操作的是自己专属的NavigationService实例,调用setActiveMenuItem时更新的是这个实例里的BehaviorSubject- 而路由加载的
ActionPageComponent注入的是根注入器的NavigationService单例,这个实例的BehaviorSubject从来没被更新过,所以只能拿到初始的Home值
解决方法非常简单:
把MenuComponent的providers数组里的NavigationService删掉!修改后的组件配置如下:
@Component({ selector: 'app-menu', templateUrl: './menu.component.html', styleUrls: ['./menu.component.scss'], providers: [MenuDatabase], // 仅保留MenuDatabase,移除NavigationService standalone: false })
这样一来,MenuComponent和所有路由组件都会注入同一个全局单例的NavigationService,当你在菜单里调用setActiveMenuItem时,所有订阅activeMenuItem$的组件(包括ActionPageComponent)都会实时收到最新的选中菜单项了。
额外提醒:
对于需要全局共享状态的服务,一定要确保只在根级别提供(要么用providedIn: 'root',要么在AppModule的providers中声明),绝对不要在组件的providers里重复声明,否则就会出现这种“各用各的实例,状态不共享”的诡异问题。
备注:内容来源于stack exchange,提问作者Brian
相关产品推荐
相关产品推荐

