【问题标题】:Cannot access bloc from a child class due to context issues?由于上下文问题,无法从子类访问 bloc?
【发布时间】: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&lt;TopRatedMovieBloc&gt;(context);

谁能帮我理解这个问题?

【问题讨论】:

    标签: flutter dart flutter-dependencies bloc


    【解决方案1】:

    您无法在initState 中访问context。 您在这里有一些选择:
    1. 将 bloc 用法移到build 方法中。
    2.覆盖didChangeDependencies并在那里使用它。第一次在initState 之后调用它,但context 可用。如果依赖项发生变化,它可能会被多次调用,因此如果您只想做一次某事 - 请检查您之前是否没有做过。
    3. 通过构造函数传递块

    原始错误消息中描述了另一个问题:

    flutter:         Good: BlocProvider<TopRatedMovieBloc>(builder: (context) => TopRatedMovieBloc())
    flutter:         Bad: BlocProvider(builder: (context) => TopRatedMovieBloc()).
    

    你需要更新_MyHomePageStatebuild方法中的代码,将类型参数添加到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 解决了这个问题。谢谢
    猜你喜欢
    • 2021-01-03
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 2014-01-21
    • 2010-12-26
    • 2019-06-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多