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

Posted

技术标签:

【中文标题】使用不包含 Bloc 类型的上下文调用 Flutter BLoC BlocProvider.of()【英文标题】:Flutter BLoC BlocProvider.of() called with a context that does not contain a Bloc of type 【发布时间】:2021-02-08 03:42:19 【问题描述】:

类似于this thread,到目前为止还没有相关的解决方案。

我收到以下错误:

BlocProvider.of() called with a context that does not contain a Bloc of type CategoryBloc.

唯一的小部件:

class _TestWidgetState extends State<TestWidget> 
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(title: Text('Test')),
      body: BlocProvider(
        builder: (context) => sl<CategoryBloc>(),   // dependency injection via GetIt
        child: Column(
          children: [
            BlocBuilder<CategoryBloc, CategoryState>(builder: (context, state) 
              if (state is Empty) 
                return Text('Empty');
              
              if (state is Loading) 
                return Text('Loading');
              
              if (state is Loaded) 
                return Text('Loaded');
              
            ),
            RaisedButton(
              child: Text('Press me'),
              onPressed: () 
                dispatchAction(context);
              ,
            ),
          ],
        ),
      ),
    );
  

  void dispatchAction(BuildContext context) 
    BlocProvider.of<CategoryBloc>(context).dispatch(GetAllCategories());
  

通过 GetIt 进行依赖注入

 sl.registerFactory(() => CategoryBloc(getAllCategories: sl()));
...

为了完整起见,我将提供所有 bloc 文件

类别组

class CategoryBloc extends Bloc<CategoryEvent, CategoryState> 
  final GetAllCategoriesUsecase getAllCategories;

  CategoryBloc(@required this.getAllCategories)
      : assert(getAllCategories != null);

  @override
  CategoryState get initialState => Empty();

  @override
  Stream<CategoryState> mapEventToState(CategoryEvent event) async* 
    if (event is GetAllCategories) 
      yield Loading();
      final failureOrCategories =
          await getAllCategories(Params(limit: 10, skip: 0));
      yield failureOrCategories.fold(
          (failure) => Error(error: _mapFailureToMessage(failure)),
          (categories) => Loaded(list: categories));
    
  

  String _mapFailureToMessage(Failure failure) 
    ...
  

类别事件

@immutable
abstract class CategoryEvent extends Equatable 
  CategoryEvent([List props = const <dynamic>[]]) : super();


class GetAllCategories extends CategoryEvent 
  @override
  List<Object> get props => [];

类别状态

@immutable
abstract class CategoryState extends Equatable 
  CategoryState([List props = const <dynamic>[]]) : super();
  @override
  List<Object> get props => [];


class Empty extends CategoryState 

class Loading extends CategoryState 

class Loaded extends CategoryState 
  final List<Category> list;

  Loaded(@required this.list);

  @override
  List<Object> get props => [list];


class Error extends CategoryState 
  final String error;

  Error(@required this.error);
  @override
  List<Object> get props => [error];

pubspec.yaml

  get_it: ^3.0.1
  flutter_bloc: ^0.21.0   # old version :(
  equatable: ^1.0.1

到目前为止我已经尝试过:

指定类型body: BlocProvider&lt;CategoryBloc&gt;( - 相同的错误

非常感谢任何帮助。

【问题讨论】:

这是解决该问题的方法:***.com/questions/65679221/… 【参考方案1】:

经过数小时的谷歌搜索找到了答案。

Flutter_bloc 要求 BlocProviderBlocBuilder 位于 单独的小部件 中,这样 Bloc Builder 的上下文就分层地“在”用于生成器。

class _TestWidgetState extends State<TestWidget> 
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(title: Text('Test')),
      body: BlocProvider<CategoryBloc>(
        builder: (context) => sl<CategoryBloc>(), //
        child: TestWidget2(),
      ),
    );
  


class TestWidget2 extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return Column(
      children: [
        BlocBuilder<CategoryBloc, CategoryState>(builder: (context, state) 
          if (state is Empty) 
            return Text('Empty');
          
          if (state is Loading) 
            return Text('Loading');
          
          if (state is Loaded) 
            return Text('Loaded');
          
        ),
        RaisedButton(
          child: Text('Press me'),
          onPressed: () 
            dispatchAction(context);
          ,
        ),
      ],
    );
  

【讨论】:

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

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

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

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

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

BlocProvider.of() 调用的上下文不包含 MyBloc 类型的 Bloc/Cubit

使用 bloc 更改屏幕