由于上下文问题,无法从子类访问 bloc?
Posted
技术标签:
【中文标题】由于上下文问题,无法从子类访问 bloc?【英文标题】:Cannot access bloc from a child class due to context issues? 【发布时间】:2019-12-16 22:22:27 【问题描述】:当我尝试从子类访问 bloc 时,它给了我一个错误
flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following assertion was thrown building Builder:
flutter: BlocProvider.of() called with a context that does not contain a Bloc of type
flutter: TopRatedMovieBloc.
flutter: No ancestor could be found starting from the context that was passed to
flutter: BlocProvider.of<TopRatedMovieBloc>().
flutter:
flutter: This can happen if:
flutter: 1. The context you used comes from a widget above the BlocProvider.
flutter: 2. You used MultiBlocProvider and didn't explicity provide the BlocProvider types.
flutter:
flutter: Good: BlocProvider<TopRatedMovieBloc>(builder: (context) => TopRatedMovieBloc())
flutter: Bad: BlocProvider(builder: (context) => TopRatedMovieBloc()).
我的代码如下所示:
**main.dart**
void main()
final MovieRepository movieRepository = MovieRepository(
movieApiClient: MovieApiClient(
httpClient: http.Client(),
),
);
BlocSupervisor.delegate = SimpleBlocDelegate();
runApp(App(movieRepository: movieRepository),
);
class App extends StatelessWidget
final MovieRepository movieRepository;
App(Key key, @required this.movieRepository)
: assert(movieRepository != null),
super(key: key);
@override
Widget build(BuildContext context)
return MaterialApp(
title: 'Flutter Infinite Scroll',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue, canvasColor: Colors.transparent),
home: MyHomePage(),
);
class MyHomePage extends StatefulWidget
@override
_MyHomePageState createState() => _MyHomePageState();
class _MyHomePageState extends State<MyHomePage>
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final MovieRepository movieRepository = MovieRepository(
movieApiClient: MovieApiClient(
httpClient: http.Client(),
),
);
@override
Widget build(BuildContext context)
return BlocBuilder<ChangeThemeBloc, ChangeThemeState>(
builder: (context, state)
return Scaffold(body: Container(
color: state.themeData.primaryColor,
child: ListView(
physics: BouncingScrollPhysics(),
children: <Widget>[
DiscoverMovies(
themeData: state.themeData,
),
BlocProvider(
builder: (BuildContext context) =>
TopRatedMovieBloc(movieRepository: movieRepository),
child: ScrollingMovies(
themeData: state.themeData,
title: 'Top Rated',
api: Api.toprated,
),
),
],
),
),
);
,
);
class ScrollingMovies extends StatefulWidget
final ThemeData themeData;
final String title;
final Api api;
ScrollingMovies(
this.themeData,
this.api,
this.title,
);
@override
_ScrollingMoviesState createState() => _ScrollingMoviesState();
class _ScrollingMoviesState extends State<ScrollingMovies>
@override
void initState()
super.initState();
TopRatedMovieBloc _topRatedMovieBloc =
BlocProvider.of<TopRatedMovieBloc>(context);
@override
Widget build(BuildContext context)
return Column(
children: <Widget>[])
这行给了我错误:
TopRatedMovieBloc _topRatedMovieBloc = BlocProvider.of<TopRatedMovieBloc>(context);
谁能帮我理解这个问题?
【问题讨论】:
【参考方案1】:您无法在initState
中访问context
。
您在这里有一些选择:
1. 将 bloc 用法移到build
方法中。
2.覆盖didChangeDependencies
并在那里使用它。第一次在initState
之后调用它,但context
可用。如果依赖项发生变化,它可能会被多次调用,因此如果您只想做一次某事 - 请检查您之前是否没有做过。
3. 通过构造函数传递块
原始错误消息中描述了另一个问题:
flutter: Good: BlocProvider<TopRatedMovieBloc>(builder: (context) => TopRatedMovieBloc())
flutter: Bad: BlocProvider(builder: (context) => TopRatedMovieBloc()).
你需要更新_MyHomePageState
build
方法中的代码,将类型参数添加到BlocProvider,所以它应该看起来像
BlocProvider<TopRatedMovieBloc>(
builder: (BuildContext context) =>
TopRatedMovieBloc(movieRepository: movieRepository),
child: ScrollingMovies(
themeData: state.themeData,
title: 'Top Rated',
api: Api.toprated,
),
),
【讨论】:
我将所有 bloc 用法移至 build 方法,但它仍然给我同样的错误? @user818455 我已经用其他问题解决方案更新了我的答案 将 type 参数添加到 BlocProvider 解决了这个问题。谢谢以上是关于由于上下文问题,无法从子类访问 bloc?的主要内容,如果未能解决你的问题,请参考以下文章
使用 BLoC 的 Flutter 导航:用于从 Navigator 推送路由的上下文必须是 Navigator 小部件的后代
使用不包含 Bloc 类型的上下文调用 Flutter BlocProvider.of()
Flutter / BLoC - 使用不包含 ArticlesBloc 类型的 Bloc 的上下文调用 BlocProvider.of()
使用不包含 Bloc 类型的上下文调用 Flutter BLoC BlocProvider.of()
BlocProvider.of() 使用不包含 Bloc<dynamic,dynamic> 类型的 Bloc 的上下文调用
Flutter Bloc:在创建的上下文中没有我的 bloc 的祖先,而我很好地为其提供了 BlocProvider.value