AutoRoute ^7.7.1迁移:如何在路由守卫中传递Bloc实例
解决auto_route 7.7.1版本中路由守卫获取Bloc/Cubit的问题
方案一:通过AppRouter构造参数注入Cubit
这种方式遵循依赖注入原则,更便于测试和维护:
修改AppRouter类,添加构造参数
在自定义的AppRouter类中添加SettingsCubit的构造参数,再在路由配置中用该参数初始化守卫:@AutoRouterConfig(replaceInRouteName: 'Page,Route') class AppRouter extends $AppRouter { final SettingsCubit settingsCubit; // 构造函数接收Cubit实例 AppRouter({required this.settingsCubit}); @override List<AutoRoute> get routes => [ AutoRoute( initial: true, page: TabsRoute.page, // 使用传入的Cubit实例创建守卫 guards: [FingerPrintGuard(settingsCubit)], children: [ // 子路由配置 ], ), ]; }创建AppRouter实例时传入Cubit
在初始化AppRouter的位置,从context中获取SettingsCubit并传入:_router = AppRouter( settingsCubit: BlocProvider.of<SettingsCubit>(context), );
方案二:在守卫中通过NavigatorContext获取Cubit
如果不想修改AppRouter的构造逻辑,可以直接在守卫里通过路由的navigatorKey获取当前上下文,进而拿到Cubit:
修改FingerPrintGuard类
删除构造参数中的SettingsCubit,改为从上下文动态获取:class FingerPrintGuard extends AutoRouteGuard { @override void onNavigation(NavigationResolver resolver, StackRouter router) async { // 获取当前导航上下文 final context = router.navigatorKey.currentContext; if (context == null) { // 上下文不存在时直接放行 resolver.next(); return; } // 从context中获取SettingsCubit final settingsCubit = BlocProvider.of<SettingsCubit>(context); resolver.next(); if (!settingsCubit.state.authenticated) { router.push(const FingerPrintRoute()); } } }简化AppRouter配置
此时AppRouter中可直接实例化守卫,无需传入参数:@AutoRouterConfig(replaceInRouteName: 'Page,Route') class AppRouter extends $AppRouter { @override List<AutoRoute> get routes => [ AutoRoute( initial: true, page: TabsRoute.page, guards: [FingerPrintGuard()], children: [ // 子路由配置 ], ), ]; }
注意事项
你已经配置的reevaluateListenable需要保留,它会在SettingsCubit状态变化时重新触发守卫评估,确保状态更新后路由权限能及时生效:
MaterialApp.router( routerConfig: _router.config( reevaluateListenable: ReevaluateListenable.stream( context.watch<SettingsCubit>().stream)), );
内容的提问来源于stack exchange,提问作者hesham shawky
相关产品推荐
相关产品推荐

