Flutter Bloc:从上下文开始找不到祖先?

Vin*_*ois 6 flutter

我是 Flutter 的新手,也是 Bloc 的新手。

编译代码时出现错误:

    The following assertion was thrown building Login(dirty, state: _LoginFormState#44e7f):
         BlocProvider.of() called with a context that does not contain a Bloc of type BtnBloc.
         No ancestor could be found starting from the context that was passed to
         BlocProvider.of<BtnBloc>().
       This can happen if the context you use comes from a widget above the BlocProvider.
         This can also happen if you used BlocProviderTree and didn't explicity provide 
         the BlocProvider types: BlocProvider(bloc: BtnBloc()) instead of BlocProvider<BtnBloc>(bloc:
         BtnBloc()).
         The context used was: Login(dirty, state: _LoginFormState#44e7f)    
Run Code Online (Sandbox Code Playgroud)

我试图改变我的集团类中的一些东西,但没有任何改变。

这是我的博客课程:

class BtnBloc extends Bloc<BtnEvent, BtnState> {
  @override
  BtnState get initialState => BtnState.initial();

  @override
  Stream<BtnState> mapEventToState(
      BtnState currentState, BtnEvent event) async* {
    if (event is IdleEvent) {
      yield currentState..state = 1;
    } else if (event is LoadingEvent) {
      yield currentState..state = 1;
    } else if (event is RevealEvent) {
      yield currentState..state = 2;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这是我的构建方法:

final _btnBloc = new BtnBloc();

  _LoginFormState(
      {Key key,
      this.primaryColor,
      this.backgroundColor,
      this.backgroundImage,
      this.logo});

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
        bloc: _btnBloc,
        child: BlocBuilder<BtnEvent, BtnState>(
            bloc: BlocProvider.of<BtnBloc>(context),
            builder: (context, BtnState state) {
return myWidget();
Run Code Online (Sandbox Code Playgroud)

请帮我 :'(

Huy*_*yen 9

在面对这个问题一段时间后,我希望这篇文章能帮助您更多地了解context. 一般解决方案与@Filled Stacks 的答案相同。这意味着您在导航到新页面时必须传递块BlocProvider,以便可以找到您将收到的块类型。

我建议初始化整个应用程序的主要功能,该功能将通过屏幕初始化您的屏幕和上下文。例如:

  • 初始化并传递 Bloc:
class ListTodoPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider<TodoBloc>(
        create: (context) => TodoBloc(TodoDao())..add(QueryTodoEvent()),
        child: ListTodoPageful());
  }
}

class ListTodoPageful extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return ListTodoState();
  }
}

class ListTodoState extends State<ListTodoPageful> {
  TodoBloc _todoBloc;
  @override
  Widget build(BuildContext context) {
    _todoBloc = BlocProvider.of<TodoBloc>(
        context);
   //...
   floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.push(
              context,
              CupertinoPageRoute(
                  builder: (context) => BlocProvider.value(
                      value: _todoBloc, child: CreateTaskPage())));
        }
  //...
}
Run Code Online (Sandbox Code Playgroud)
  • 接收块:
class _CreatePageState extends State<CreateTaskPage> {
  TodoBloc _todoBloc;

  @override
  Widget build(BuildContext context) {
    _todoBloc = BlocProvider.of<TodoBloc>(context);
}
Run Code Online (Sandbox Code Playgroud)

请参阅我的示例应用程序: https: //github.com/huynguyennovem/flutter_todo


Fil*_*cks 5

下面这行是你的问题。该错误正是消息所说的。

...
child: BlocBuilder<BtnEvent, BtnState>(
     bloc: BlocProvider.of<BtnBloc>(context), <------- Problem line
     builder: (context, BtnState state) {
...
Run Code Online (Sandbox Code Playgroud)

您在那里使用的上下文没有附加 BlocBuilder,因此没有任何东西可以将 BloC 从顶部传递到您的 LoginState。你可以

  1. 使用您现有的块(_btnBloc)并将其传入(推荐
  2. 使用 BlocProvider 包装将 LoginState 放在屏幕上的小部件,以便您可以在小部件状态下访问它。

如果这是您第一次查看,请使用 1。

改变

 bloc: BlocProvider.of<BtnBloc>(context), <------- Problem line
Run Code Online (Sandbox Code Playgroud)

bloc: _btnBloc
Run Code Online (Sandbox Code Playgroud)