Flutter调用Bloc前显示确认弹窗遇BlocProvider上下文错误怎么解决?
解决BlocProvider找不到DatasendBloc的问题
错误原因
你用dialogContext获取Bloc时出现问题,因为dialogContext是AlertDialog的上下文——Dialog是挂载在Navigator的Overlay层上的,它的上下文树和当前页面(SaveformApp)的上下文树完全分离,自然找不到页面中配置的DatasendBloc。
解决方案
方案1:使用传入的页面上下文获取Bloc
直接将弹窗中获取Bloc的代码,改成用_showConfirmationDialog函数接收的context(也就是ListView.builder传递过来的页面上下文):
修改弹窗OK按钮的onPressed逻辑:
onPressed: () async { try { // 替换成传入的context,而非dialogContext BlocProvider.of<DatasendBloc>(context).add(SendData(model)); } catch (e) { print(e); await NotificationService.showNotification( title: "Fail", body: "Error occurred, please try again", ); } Navigator.pop(dialogContext); }
方案2:提前获取Bloc并传入弹窗函数
如果担心上下文混淆,也可以在调用弹窗前先拿到Bloc实例,再传递给弹窗函数:
- 修改弹窗函数定义:
void _showConfirmationDialog(BuildContext context, DatasendBloc bloc, postmodel model) { showDialog( context: context, builder: (BuildContext dialogContext) { return AlertDialog( title: Text('Confirm Action'), content: Text('Do you want to perform this action?'), actions: <Widget>[ TextButton( child: Text('Cancel'), onPressed: () { Navigator.pop(dialogContext); }, ), TextButton( child: Text('OK'), onPressed: () async { try { bloc.add(SendData(model)); // 直接使用传入的bloc实例 } catch (e) { print(e); await NotificationService.showNotification( title: "Fail", body: "Error occurred, please try again", ); } Navigator.pop(dialogContext); }, ), ], ); }, ); }
- 调用弹窗时传入Bloc:
// 从页面上下文获取Bloc,再传给弹窗函数 _showConfirmationDialog(context, BlocProvider.of<DatasendBloc>(context), model);
额外检查
确认SaveformApp页面中所有需要访问DatasendBloc的组件,都处于BlocProvider的包裹范围内——从你的跳转代码来看,BlocProvider.value已经正确包裹了SaveformApp,这部分无需调整。
内容的提问来源于stack exchange,提问作者ayman
相关产品推荐
相关产品推荐

