无法在 Flutter 的 showModal 上下文中访问 bloc

Sin*_*ina 6 dart flutter flutter-bloc

我包裹我的脚手架dart BlocProvider<ABloc,AState> 但是当我使用showDialog func 和showDialog时,我想从上下文访问 ABloc 或者BlocBuilder 不包含 bloc 并抛出错误,有没有办法在这种情况下访问 bloc (在我的对话框中,我显示提交的文本以获取用户名,所以我想访问 bloc)

class MyHomePageState extends StateLessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
        lazy: false,
        create: (context) => EditColorBloc(context.bloc<RetrieveColorBloc>()),
        child: MainScafold());
  }
}
Run Code Online (Sandbox Code Playgroud)
class MainScafold extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("sina"),
      ),
      floatingActionButton:FloatingActionButton(
            child: Icon(Icons.add),
            onPressed: () => showDialog(
              context: context,
              builder: (ctx) {
              // show dialog and use 
              // context o BlocBuilder to access 
              // EditColorBloc
              // throw error BlocProvider.of() called with a context that does 
              // not contain a Cubit of type EditColorBloc
              }
           )
  }
}
Run Code Online (Sandbox Code Playgroud)

hma*_*des 5

更新v6.1.0

(感谢@Sebastian Dennis

context.bloc已被弃用,取而代之的是提供商的context.readcontext.watchcontext.select。在下面的代码中,只需更改context.bloc<TestBloc>context.read<TestBloc>


您不应该使用 aBlocBuilder来包装Dialog. Dialog原因是,每当发生更改时,您(很可能)不会重建整体。另一个更重要的原因是构建 your 的上下文Dialog不包含 your bloc,因此您需要将bloc实例注入到Dialogs中context

相反,使用参数BlocProvider.value并将其设置valueBlocProvider.of(context)(aka context.bloc()),并确保上下文不是 的showDailog方法上下文,而是原始方法中的上下文build

这是一个工作示例。您只需将TestBlocTestState等更改为您自己的Bloc实例:

  @override
  Widget build(BuildContext context) {
    return BlocProvider<TestBloc>(
        create: (context) => TestBloc(InitTestState()),
        child: Scaffold(
            body: BlocBuilder<TestBloc, TestState>(
              builder: (context, state) => Center(
                child: FlatButton(
                  child: Text("Show Dialog"), 
                  onPressed: () => showDialog(
                      context: context, 

                      // Relavent code change here
                      builder: (ctx) => BlocProvider<TestBloc>.value(
                        value: context.bloc<TestBloc>(), 

                        child: Dialog(
                          child: FlatButton(
                            child: Text("Notify bloc"),
                            onPressed: () => context
                                .bloc<TestBloc>()
                                .add(TestEvent()),
                          ),
                        ),
                      )),
            ),
          ),
        )));
Run Code Online (Sandbox Code Playgroud)