Flutter / BLoC - 使用不包含 ArticlesBloc 类型的 Bloc 的上下文调用 BlocProvider.of()

Posted

技术标签:

【中文标题】Flutter / BLoC - 使用不包含 ArticlesBloc 类型的 Bloc 的上下文调用 BlocProvider.of()【英文标题】:Flutter / BLoC - BlocProvider.of() called with a context that does not contain a Bloc of type ArticlesBloc 【发布时间】:2020-08-21 12:01:17 【问题描述】:

我正在使用 BLoC 模式开发一个新的 Flutter Mobile 应用程序。但我有一个问题,我还没有找到解决方案。 我有三个小部件:

第一个是我的主页,带抽屉 感谢抽屉,我可以导航到我的第二个小部件,即文章列表 最后一个小部件:文章详细信息(我可以通过点击列表中的文章来访问它)

我的问题在第二个和第三个之间。当我点击一篇文章时,我有一个错误:BlocProvider.of() called with a context that does not contain a Bloc of type ArticlesBloc.

我的 MaterialApp 路由属性中有这个

MyRoutes.articleList: (context) => BlocProvider<ArticlesBloc>(
              create: (context) => ArticlesBloc()..add(ArticlesLoaded()),
              child: ArticlesScreen(),
            ),

这是我的文章列表正文:

body: BlocBuilder<ArticlesBloc, ArticlesState>(
        builder: (BuildContext buildContext, state) 
          if (state is ArticlesLoadSuccess) 
            final articles = state.articles;
            return ListView.builder(
              itemCount: articles.length,
              itemBuilder: (BuildContext context, int index) 
                final article = articles[index];
                return ArticleItem(
                    onTap: () 
                      Navigator.of(buildContext).push(
                        MaterialPageRoute(builder: (_) 
                          return ArticleDetailScreen(id: article.id);
                        ),
                      );
                    ,
                    article: article);
              ,
            );
          
        ,
      ),

还有我的文章详情页:

@override
  Widget build(BuildContext context) 
    return BlocBuilder<ArticlesBloc, ArticlesState>(builder: (context, state) 
      final Article article = (state as ArticlesLoadSuccess)
          .articles
          .firstWhere((article) => article.id == id, orElse: () => null);
      return Scaffold(
        appBar: AppBar(
          title: Text(article.reference + ' - Article details'),
        ),
        body: id == null
            ? Container()
            : Padding(
                padding: EdgeInsets.all(16.0),
                child: ListView(
                  children: [
                    Row(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Expanded(
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Hero(
                                tag: '$article.id__heroTag',
                                child: Container(
                                  width: MediaQuery.of(context).size.width,
                                  child: Text(
                                    article.designation,
                                  ),
                                ),
                              ),
                            ],
                          ),
                        ),
                      ],
                    ),
                  ],
                ),
              ),
      );
    );
  

请多多指教^^

编辑 1:我找到了解决方案,但我不知道它是否正确。我不只是将 id 传递给详细信息屏幕,而是传递了完整的文章,因此我可以直接返回 Scaffold 而无需 BlocBuilder

【问题讨论】:

【参考方案1】:

您需要通过ArticleDetailScreen 向您的新路线提供您的集团。 像这样:

MaterialPageRoute(builder: (_) 
  return BlocProvider.value(
    value: BlocProvider.of<ArticlesBloc>(context),
    child: ArticleDetailScreen(id: article.id),
  );
)

【讨论】:

以上是关于Flutter / BLoC - 使用不包含 ArticlesBloc 类型的 Bloc 的上下文调用 BlocProvider.of()的主要内容,如果未能解决你的问题,请参考以下文章

使用不包含 Bloc 类型的上下文调用 Flutter BlocProvider.of()

BlocProvider.of() 使用不包含 Bloc<dynamic,dynamic> 类型的 Bloc 的上下文调用

使用不包含 PhoneAuthenticationBloc 类型的 Bloc 的上下文调用 BlocProvider.of()。扑

使用 Bloc/Cubit 进行 Flutter 状态管理

将flutter_bloc与tabview一起使用

flutter - bloc - 我如何在我的 Ui 中使用 FutureBuilder 来正确实现 Bloc 架构