如何在initState方法中访问flutter bloc?

时间:2019-09-07 15:06:17

标签: flutter dart bloc

在下面显示的代码中,在获取BuildContext对象之后,在build方法中调用dispatch事件。如果我想做的是在initState方法本身内的页面开始时在处理过程中调度一个事件,该怎么办?

如果我使用didChangeDependencies方法,则出现此错误: BlocProvider.of() called with a context that does not contain a Bloc of type FileManagerBloc.如何解决?

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: BlocProvider<FileManagerBloc>(
          builder: (context)=>FileManagerBloc(),
          child: SafeArea(
      child: Container(
          child: Column(
            children: <Widget>[
              Container(color: Colors.blueGrey, child: TopMenuBar()),
              Expanded(
                child: BlocBuilder<FileManagerBloc,FileManagerState>(
                  builder: (context , state){
                    return GridView.count(
                      scrollDirection: Axis.vertical,
                      physics: ScrollPhysics(),
                      crossAxisCount: 3,
                      crossAxisSpacing: 10,
                      children: getFilesListWidget(context , state),
                    );
                  },
                ),
              )
            ],
          ),
      ),
    ),
        ));
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  void didChangeDependencies() {
    logger.i('Did change dependency Called');
    final FileManagerBloc bloc = BlocProvider.of<FileManagerBloc>(context) ;
    Messenger.sendGetHomeDir()
        .then((path) async {
      final files = await Messenger.sendListDir(path);
        bloc.dispatch(SetCurrentWorkingDir(path)) ;
        bloc.dispatch(UpdateFileSystemCacheMapping(path , files)) ;
    });
  }

2 个答案:

答案 0 :(得分:1)

问题是您正在FileManagerBloc内初始化BlocProvider的实例,而父窗口小部件当然无法访问它。我知道这有助于自动清除Bloc,但是如果要在initStatedidChangeDependencies内部访问它,则必须像这样在父级进行初始化,

FileManagerBloc _fileManagerBloc;

@override
void initState() {
  super.initState();
  _fileManagerBloc= FileManagerBloc();
  _fileManagerBloc.dispatch(LoadEducation());
}

@override
  Widget build(BuildContext context) {
    return Scaffold(
        body: BlocProvider<FileManagerBloc>(
          builder: (context)=> _fileManagerBloc,
          child: SafeArea(
      child: Container(
          child: Column(
            children: <Widget>[
              Container(color: Colors.blueGrey, child: TopMenuBar()),
              Expanded(
                child: BlocBuilder<FileManagerBloc,FileManagerState>(
                  builder: (context , state){
                    return GridView.count(
                      scrollDirection: Axis.vertical,
                      physics: ScrollPhysics(),
                      crossAxisCount: 3,
                      crossAxisSpacing: 10,
                      children: getFilesListWidget(context , state),
                    );
                  },
                ),
              )
            ],
          ),
      ),
    ),
        ));
  }

  @override
  void dispose() {
    _fileManagerBloc.dispose();
    super.dispose();
  }

  @override
  void didChangeDependencies() {
    logger.i('Did change dependency Called');
    Messenger.sendGetHomeDir()
        .then((path) async {
      final files = await Messenger.sendListDir(path);
        _fileManagerBloc.dispatch(SetCurrentWorkingDir(path)) ;
        _fileManagerBloc.dispatch(UpdateFileSystemCacheMapping(path , files)) ;
    });
  }

或者,如果FileManagerBloc是在祖父母Widget处提供/初始化的,则可以通过thisBlocProvider.of<CounterBloc>(context);级别轻松访问它

答案 1 :(得分:0)

您可以通过didChangeDependencies方法而不是initState使用它。

示例

 @override
  void didChangeDependencies() {
    final CounterBloc counterBloc = BlocProvider.of<CounterBloc>(context);
    //do whatever you want with the bloc here.
    super.didChangeDependencies();
  }