如何解决在对话框中使用BLoC:找不到正确的提供者
我正在尝试使用集团来管理对话框的内容。我对扑扑还挺陌生的。
页面定义为:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Business Region Manager"),),body: MultiBlocProvider(
providers: [
BlocProvider(
create: (context) =>
EntityModifyBloc(repository: widget.repository),BlocProvider(
create: (context) => EntityBloc(
repository: widget.repository,modifyBloc: BlocProvider.of<EntityModifyBloc>(context)),BlocProvider(
create: (context) => BusinessRegionBloc(repository: widget.repository),],child: Center(
child: BusinessRegionPage(widget.business),));
}
在BusinessRegionPage内部,我使用了EntityBloc和EntityModifyBloc,而且至少我认为我是正确的。 该页面具有一个回调,该回调在触发时调用方法:
void onAddBusinessRegion(){
showDialog(context: context,barrierDismissible: false,builder: (BuildContext context){
return BusinessRegionDialog(
positiveText: "Ok",onPositive: onPositive,negativeText: 'Cancel',onNegative: onNegative,businessId: widget.business.id,);
});
}
BusinessRegionDialog是一个有状态的小部件,状态实现的构建为:
@override
Widget build(BuildContext context) {
return BlocBuilder<BusinessRegionBloc,BusinessRegionState>(builder: (context,state) {
if (state is BusinessRegionEmpty) {
BlocProvider.of<BusinessRegionBloc>(context).add(GetBusinessRegions(widget.businessId));
}
if (state is BusinessRegionError) {
return Center(
child: Text('Busines Region Error'),);
}
if (state is BusinessRegionLoaded) {
return Center(
child: Text('BusinessRegionLoaded'),);
}
return Center(
child: CircularProgressIndicator(),);
});
触发回调后,我收到消息:
错误:在此BlocBuilder
这可能是因为您使用的BuildContext
不包含提供商
您的选择。
我假设在对ShowDialog(context)的调用中,上下文与传递给build的上下文相同吗?我通过在showDialog调用之前以及在BusinessRegionPage上的构建实现之后打印上下文的hashCode来检查此假设,
错误消息中的一个提示是:
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),builder: (context) {
return Text(context.watch<Example>()),}
),}
所以我尝试了:
void onAddBusinessRegion() {
print("OnAddCallback: " + context.hashCode.toString());
BusinessRegionClient brClient = BusinessRegionClient(client: http.Client());
BusinessRegionRepository brRepository =
BusinessRegionRepository(client: brClient);
showDialog(
context: context,builder: (BuildContext context) {
return Provider<BusinessRegionBloc>(
create: (_) => BusinessRegionBloc(repository: brRepository),builder: (context) {
return BusinessRegionDialog(
positiveText: "Ok",);
});
});
}
IDE告诉我: 无法将参数类型'BusinessRegionDialog Function(BuildContext)'分配给参数类型'Widget Function(BuildContext,Widget)'。
我显然不明白。我要做的就是用来自我的存储库的Future的信息填充一个对话框。任何指导将不胜感激。
解决方法
由于这样输入,我终于知道了:
Flutter: bloc,how to show an alert dialog
这里的答案是使用堆栈使对话框和页面共存,并在侦听器具有正确状态时显示对话框。答案使用StatelessWidget来管理SnackBar。为了能够将事件添加到集团中,我使用了StatefulWidget。
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Business Region Manager"),),body: MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => EntityModifyBloc(
repository: xbrRepository),//widget.repository),BlocProvider(
create: (context) => EntityBloc(
repository: xbrRepository,//widget.repository,modifyBloc: BlocProvider.of<EntityModifyBloc>(context)),BlocProvider(
create: (context) => BusinessRegionDialogBloc(
repository: xbrRepository),],child: Stack(children: [
BusinessRegionDialogManager(widget.business.id),Center(child: BusinessRegionPage(widget.business)),]),));
}
class BusinessRegionDialogManager extends StatefulWidget {
final int businessId;
BusinessRegionDialogManager(this.businessId);
State<BusinessRegionDialogManager> createState() =>
_BusinessRegionDialogManagerState();
}
类_BusinessRegionDialogManagerState 扩展状态{
// Callback functions from the dialog so can have access to
// BusinessRegionDialogBloc
void xnPositive(List<Region> addedRegions) {
BlocProvider.of<BusinessRegionDialogBloc>(context)
.add(AddBusinessRegions(addedRegions,widget.businessId));
}
void xnNegative(){
}
@override
Widget build(BuildContext context) {
return BlocListener<BusinessRegionDialogBloc,BusinessRegionDialogState>(
listener: (context,state) {
if (state is RegionDialogLoaded) {
showDialog(
context: context,barrierDismissible: false,builder: (BuildContext context) {
return BusinessRegionDialog(
onPositive: xnPositive,onNegative: xnNegative,regions: state.regions,);
})
}
},child: Container(),);
}
,
你需要做的是创建一个 BlocTypeA 的提供者将它传递给孩子。创建一个对话与另一个 context2 使用 provider.value 传递 bloc 然后 使用context2构建它的子组件,并在子组件内部使用previus context .read with BlocTypeA...访问bloc...因此它解决了
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。