Flutter 在对话框中使用BLoC:找不到正确的提供程序

Flutter 在对话框中使用BLoC:找不到正确的提供程序,flutter,dialog,bloc,Flutter,Dialog,Bloc,我正在尝试使用一个bloc来管理对话框的内容。我是个新手 该页面定义为: @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Business Region Manager"), ), body: MultiBlocProvider( providers: [ BlocProv

我正在尝试使用一个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),
      ),
    ));
}
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(),
    );
  });
所以我试着:

void onAddBusinessRegion() {
  print("OnAddCallback: " + context.hashCode.toString());
  BusinessRegionClient brClient = BusinessRegionClient(client: http.Client());
  BusinessRegionRepository brRepository =
      BusinessRegionRepository(client: brClient);

  showDialog(
    context: context,
    barrierDismissible: false,
    builder: (BuildContext context) {
      return Provider<BusinessRegionBloc>(
          create: (_) => BusinessRegionBloc(repository: brRepository),
          builder: (context) {
            return BusinessRegionDialog(
              positiveText: "Ok",
              onPositive: onPositive,
              negativeText: 'Cancel',
              onNegative: onNegative,
              businessId: widget.business.id,
            );
          });
    });
}
void onAddBusinessRegion(){
打印(“OnAddCallback:+context.hashCode.toString());
BusinessRegionClient brClient=BusinessRegionClient(客户端:http.client());
BusinessRegionRepository brRepository=
BusinessRegionRepository(客户:brClient);
显示对话框(
上下文:上下文,
禁止:错误,
生成器:(BuildContext上下文){
返回提供者(
创建:()=>BusinessRegionBloc(存储库:brRepository),
生成器:(上下文){
返回业务区域对话(
肯定文字:“好的”,
onPositive:onPositive,
negativeText:'取消',
否定的,否定的,
businessId:widget.business.id,
);
});
});
}
IDE告诉我: 无法将参数类型“BusinessRegionDialog Function(BuildContext)”分配给参数类型“Widget Function(BuildContext,Widget)”


我显然不明白什么。我所要做的就是用我的存储库中未来的信息填充一个对话框。任何指导都将不胜感激。

多亏了so条目,我终于找到了答案:

这里的答案是使用堆栈使对话框和页面共存,并在侦听器的状态正确时显示对话框。答案使用了一个无状态小部件来管理SnackBar(在答案中)。为了能够向bloc添加事件,我使用了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();
}
@覆盖
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(“业务区域经理”),
),
主体:MultiBlocProvider(
供应商:[
BlocProvider(
创建:(上下文)=>EntityModifyBloc(
repository:XBRepository),//widget.repository),
),
BlocProvider(
创建:(上下文)=>EntityBloc(
repository:XBRepository,//widget.repository,
modifyBloc:BlocProvider.of(上下文)),
),
BlocProvider(
创建:(上下文)=>BusinessRegionDialogBloc(
存储库:XBRepository),
),
],
子:堆栈(子:[
BusinessRegionDialogManager(widget.business.id),
中心(子:BusinessRegionPage(widget.business)),
]),
));
}
类BusinessRegionDialogManager扩展StatefulWidget{
最终int businessId;
BusinessRegionDialogManager(this.businessId);
状态createState()=>
_BusinessRegionDialogManagerState();
}
class\u businessRegionDialogManager状态 扩展状态{

// 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(),
  );
}
//对话框中的回调函数,以便可以访问
//商业区域DialogBloc
void xnPositive(列表添加区域){
BlocProvider.of(上下文)
.add(AddBusinessRegions(addedRegions,widget.businessId));
}
void xnNegative(){
}
@凌驾
小部件构建(构建上下文){
返回BlocListener(
侦听器:(上下文、状态){
如果(状态为RegionDialogLoaded){
显示对话框(
上下文:上下文,
禁止:错误,
生成器:(BuildContext上下文){
返回业务区域对话(
onPositive:xnPositive,
否定的,否定的,
地区:州。地区,
);
})
}
},
子级:容器(),
);
}

你需要做的是创建BlocTypeA的提供者并将其传递给子对象。使用另一个context2创建一个对话框使用提供者传递bloc.value,然后使用context2构建其子对象并在子窗口小部件内使用previus上下文访问bloc。使用BlocTypeA阅读…因此我可以问题解决了

@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();
}
// 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(),
  );
}