Flutter / BLo C - BlocProvider.of () вызывается с контекстом, не содержащим Blo c типа ArticlesBloc - PullRequest
2 голосов
/ 06 мая 2020

Я разрабатываю новое приложение Flutter Mobile, используя шаблон BLo C. Но у меня проблема, и я пока не нахожу решения. У меня есть три виджета:

  • Первый - моя домашняя страница с ящиком
  • Благодаря ящику я могу перейти ко второму виджету, списку статей
  • И последний виджет: сведения о статье (я могу добраться до него, нажав на статью в списке)

Моя проблема находится между второй и третьей. Когда я нажимаю на статью, появляется ошибка: 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,
                                  ),
                                ),
                              ),
                            ],
                          ),
                        ),
                      ],
                    ),
                  ],
                ),
              ),
      );
    });
  }

Пожалуйста, heeeelp ^^

Редактировать 1: Я нашел решение, но не знаю, правильный ли он путь . Вместо того, чтобы передавать только идентификатор на экран с подробностями, я передаю всю статью, чтобы я мог напрямую вернуть Scaffold без BlocBuilder

1 Ответ

3 голосов
/ 06 мая 2020

Вам необходимо указать свой blo c для вашего нового маршрута с помощью ArticleDetailScreen. Как это:

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