这是我的项目的构建方式:
我有一个 router.dart 文件,用于管理路由
class MainRouter {
GoRouter router = GoRouter {
//...
}
}
我将此 GoRouter 对象传递到我的 MaterialApp.router-Widget 中:
class MyApp extends StatelessWidget {
MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: MainRouter.router
//..
)
}
我将 BuildContext 作为我的 AppEvent 的属性。
class AppEvent extends Equatable {
final BuildContext context;
const AppEvent(this.context);
@override
List<Object> get props => [context];
}
现在,我的 AppBloc 中有一个异步回调函数,我需要先从数据库中删除某些内容,然后导航到主屏幕。
void _onAsyncFunction(AppEvent event, Emitter<AppState> emit) async {
await _deleteDatabase();
event.context.go("/home");
}
问题是,我在项目中遇到以下 lint 问题:“不要跨异步间隙使用‘BuildContext’s。”
我知道,根据这个问题,我可以用
event.context.mounted
检查以确保BuildContext已安装,但我仍然有那个lint问题。
我尝试直接访问
MainRouter.router
并调用 MainRouter.router.go("/home")
并且成功了,但这会违反 GoRouter 或 Bloc 架构的任何架构规则吗?
感谢您的见解!
您可以使用 BlocConsumer 来监听特定的 BLoC 状态,这是一个定义的状态,指示您应该转到该路线。
class AppPopState extends AppState {
const AppPopState()
}
然后在您的 BLoC 返回该状态:
void _onAsyncFunction(AppEvent event, Emitter<AppState> emit) async {
await _deleteDatabase();
emit(const AppPopState());
}
在小部件中监听该状态:
Widget build(context) {
return BlocConsumer(
listenWhen: (_, state) => state is AppPopState,
listener: (ctx, statte) {
context.go("/home");
},
...
为您的 GoRouter 定义一个全局密钥,并使用它从您的 BLoC 进行导航。
/// Root navigator key.
final GlobalKey<NavigatorState> rootNavigatorKey = GlobalKey<NavigatorState>();
/// Navigation router.
final GoRouter kRouter = new GoRouter(
navigatorKey: rootNavigatorKey,
...
void _onAsyncFunction(AppEvent event, Emitter<AppState> emit) async {
await _deleteDatabase();
rootNavigatorKey.currentContext!.go("/home");
}