Поставщик дротиков: недоступен у ближайшего ребенка - PullRequest
0 голосов
/ 13 января 2020
  @override
  Widget build(BuildContext context) {
    return BlocProvider<HomeBloc>(
        create: (context) {
          return HomeBloc(homeRepo: HomeRepository());
        },
        child: BlocProvider.of<HomeBloc>(context).state is HomeStateLoading
            ? CircularProgressIndicator()
            : Container());
  }

Я запутался с ошибкой:

BlocProvider.of() called with a context that does not contain a Bloc of type HomeBloc.
No ancestor could be found starting from the context that was passed to
BlocProvider.of<HomeBloc>().

Разве я не создал HomeBloc у его непосредственного родителя? Чего это хочет?

Ответы [ 2 ]

1 голос
/ 14 января 2020

Вы используете context, переданный в метод build вашего класса виджетов, для поиска родителя BlocProvider. Однако этот контекст является деревом виджетов, насколько ваш класс виджетов его видит. По этой причине ваш BlocProvider.of ищет BlocProvider, который является родителем вашего класса виджетов . Если вы хотите получить поставщика, который является непосредственным родителем, вам нужен новый объект context, в котором BlocProvider является предком в дереве виджетов. Самый простой способ сделать это с помощью виджета Builder:

@override
Widget build(BuildContext context) {
  return BlocProvider<HomeBloc>(
    create: (context) {
      return HomeBloc(homeRepo: HomeRepository());
    },
    child: Builder(
      builder: (newContext) => BlocProvider.of<HomeBloc>(newContext).state is HomeStateLoading
          ? CircularProgressIndicator()
          : Container(),
    ),
  );
}

При этом достаточно создать поставщика, а затем сразу же почитать поставщика. Поставщики предназначены для извлечения вещей дальше по дереву виджетов, а не для непосредственных потомков. В этом случае использование провайдера является излишним, и на самом деле нет никаких оснований не просто указывать блоку c поле вашего класса и ссылаться на него напрямую.

0 голосов
/ 14 января 2020

Из документации :

Самый простой способ прочитать значение - использовать метод Provider.of (контекст BuildContext) stati c.

Этот метод ищет в дереве виджетов, начиная с виджета, связанного с переданным BuildContext, и возвращает ближайшую найденную переменную типа T (или throw, если ничего не найдено).

In в вашем случае он начинает поиск дерева виджетов по всему виджету (связанному с BuildContext).

Поэтому вам нужно переместить BlocProvider, чтобы стать предком этого виджета.

Если по какой-либо причине это невозможно, вы можете использовать Consumer, что позволяет получить значение от поставщика, если у вас нет BuildContext, который является потомком указанного поставщика.

Читать https://pub.dev/documentation/provider/latest/provider/Consumer-class.html

...