最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

flutter - How do I access a Bloc declared in MultiBlocProvider from a page accessed via a route? - Stack Overflow

programmeradmin4浏览0评论

I'm relatively new to Flutter and Bloc and am confused on how to use the MultiBlocProvider correctly. I have a list page and a create page, to create an item for the list.

I've tried:

  • putting the MultiBlocProvider above the Scaffold of the ListPage, having the MBP create the blocs for the list and the create page, and then when the app routes to the create page via the Scaffold's FAB, using BlocProvider.of<TodoBloc> to access the create bloc. This gets an error saying 'No ancestor could be found'

  • I have a BlocBuilder on the FAB and I've tried both the ListBloc and TodoBloc on the BlocBuilder but neither one worked. I tried moving the BlocBuilder above the Scaffold, but still got the error

I don't know if I have something set incorrectly, something in the wrong place, missing something, does the MultiBlocProvider just not work like that, does the context not carry across routes?

I know I can do BlocProvider(create:) in the createPage, but I wanted it higher so that the list page could react if there was a failure.

ListPage where I have the MultiBlocProvider:

class ListPage extends StatelessWidget {
  const ListPage ({super.key});
  @override
  Widget build(BuildContext context) {
    return MultiBlocProvider(
      providers: [
        BlocProvider<ListBloc>(
          create: (context) => ListBloc(
              todosRepository: context.read<TodoRepository>(),
            )
          },
        ),
        BlocProvider(
          create: (context) => TodoBloc(
            todosRepository: context.read<TodoRepository>(),
          ),),],
      child: const ListView(),
    );}}

ListView has the Scaffold with the FAB-> route to the create page

class ListView extends StatelessWidget {
  const ListView ({super.key});
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: {... list shows here...},
      floatingActionButton: BlocBuilder<TodoBloc, TodoState>(
          builder: (context, state) {
            return FloatingActionButton(
              onPressed: () async {
                  await Navigator.of(context).push(
                    TodoPage.createRoute(),
                  ); } )})}; )
}

And below is the route for the TodoPage where I use BlocProvider.of

class TodoPage extends StatelessWidget {
  const TodoPage({super.key});

  static Route<void> createRoute() {
    return MaterialPageRoute(
      builder: (context) => BlocProvider.value(
// This is where I get the error
        value: BlocProvider.of<TodoBloc>(context),
        child: const TodoPage(),
      ),);}

and the error:

BlocProvider.of() called with context that does not contain a TodoBloc
No ancestor could be found starting from the context that was passed to BlocProvider.of<TodoBloc>().
The context used was: Builder(dirty)

I'm relatively new to Flutter and Bloc and am confused on how to use the MultiBlocProvider correctly. I have a list page and a create page, to create an item for the list.

I've tried:

  • putting the MultiBlocProvider above the Scaffold of the ListPage, having the MBP create the blocs for the list and the create page, and then when the app routes to the create page via the Scaffold's FAB, using BlocProvider.of<TodoBloc> to access the create bloc. This gets an error saying 'No ancestor could be found'

  • I have a BlocBuilder on the FAB and I've tried both the ListBloc and TodoBloc on the BlocBuilder but neither one worked. I tried moving the BlocBuilder above the Scaffold, but still got the error

I don't know if I have something set incorrectly, something in the wrong place, missing something, does the MultiBlocProvider just not work like that, does the context not carry across routes?

I know I can do BlocProvider(create:) in the createPage, but I wanted it higher so that the list page could react if there was a failure.

ListPage where I have the MultiBlocProvider:

class ListPage extends StatelessWidget {
  const ListPage ({super.key});
  @override
  Widget build(BuildContext context) {
    return MultiBlocProvider(
      providers: [
        BlocProvider<ListBloc>(
          create: (context) => ListBloc(
              todosRepository: context.read<TodoRepository>(),
            )
          },
        ),
        BlocProvider(
          create: (context) => TodoBloc(
            todosRepository: context.read<TodoRepository>(),
          ),),],
      child: const ListView(),
    );}}

ListView has the Scaffold with the FAB-> route to the create page

class ListView extends StatelessWidget {
  const ListView ({super.key});
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: {... list shows here...},
      floatingActionButton: BlocBuilder<TodoBloc, TodoState>(
          builder: (context, state) {
            return FloatingActionButton(
              onPressed: () async {
                  await Navigator.of(context).push(
                    TodoPage.createRoute(),
                  ); } )})}; )
}

And below is the route for the TodoPage where I use BlocProvider.of

class TodoPage extends StatelessWidget {
  const TodoPage({super.key});

  static Route<void> createRoute() {
    return MaterialPageRoute(
      builder: (context) => BlocProvider.value(
// This is where I get the error
        value: BlocProvider.of<TodoBloc>(context),
        child: const TodoPage(),
      ),);}

and the error:

BlocProvider.of() called with context that does not contain a TodoBloc
No ancestor could be found starting from the context that was passed to BlocProvider.of<TodoBloc>().
The context used was: Builder(dirty)
Share Improve this question asked Feb 17 at 0:00 intrepidSequences839intrepidSequences839 111 bronze badge New contributor intrepidSequences839 is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
Add a comment  | 

1 Answer 1

Reset to default 0

I will suggest passing TodoBloc instance as argument into route while it is static

 static Route<void> createRoute(TodoBloc value) {
    return MaterialPageRoute(
      builder: (context) => BlocProvider.value(
        value: value,
        child: const TodoPage(),
      ),
    );
  }
发布评论

评论列表(0)

  1. 暂无评论