由于上下文问题,无法从 child class 访问 bloc?
Cannot access bloc from a child class due to context issues?
当我尝试从 child class 访问 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);
谁能帮我理解这个问题?
您无法在 initState
中访问 context
。
您在这里有一些选择:
1. 将 bloc 用法移动到 build
方法中。
2. 覆盖 didChangeDependencies
并在那里使用它。第一次在 initState
之后立即调用,但 context
可用。如果依赖关系发生变化,它可能会被调用多次,所以如果你只想做一次 - 检查你之前是否没有做过。
3. 通过构造函数传递 bloc
原始错误消息中描述了另一个问题:
flutter: Good: BlocProvider<TopRatedMovieBloc>(builder: (context) => TopRatedMovieBloc())
flutter: Bad: BlocProvider(builder: (context) => TopRatedMovieBloc()).
您需要通过向 BlocProvider 添加类型参数来更新 _MyHomePageState
build
方法中的代码,因此它应该类似于
BlocProvider<TopRatedMovieBloc>(
builder: (BuildContext context) =>
TopRatedMovieBloc(movieRepository: movieRepository),
child: ScrollingMovies(
themeData: state.themeData,
title: 'Top Rated',
api: Api.toprated,
),
),
当我尝试从 child class 访问 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);
谁能帮我理解这个问题?
您无法在 initState
中访问 context
。
您在这里有一些选择:
1. 将 bloc 用法移动到 build
方法中。
2. 覆盖 didChangeDependencies
并在那里使用它。第一次在 initState
之后立即调用,但 context
可用。如果依赖关系发生变化,它可能会被调用多次,所以如果你只想做一次 - 检查你之前是否没有做过。
3. 通过构造函数传递 bloc
原始错误消息中描述了另一个问题:
flutter: Good: BlocProvider<TopRatedMovieBloc>(builder: (context) => TopRatedMovieBloc())
flutter: Bad: BlocProvider(builder: (context) => TopRatedMovieBloc()).
您需要通过向 BlocProvider 添加类型参数来更新 _MyHomePageState
build
方法中的代码,因此它应该类似于
BlocProvider<TopRatedMovieBloc>(
builder: (BuildContext context) =>
TopRatedMovieBloc(movieRepository: movieRepository),
child: ScrollingMovies(
themeData: state.themeData,
title: 'Top Rated',
api: Api.toprated,
),
),