如何在 initState 方法中访问颤振块?
Posted
技术标签:
【中文标题】如何在 initState 方法中访问颤振块?【英文标题】:how to access flutter bloc in the initState method? 【发布时间】:2020-01-10 02:13:18 【问题描述】:在下面显示的代码中,在获取 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)) ;
);
【问题讨论】:
【参考方案1】:您可以在didChangeDependencies
方法而不是initState
中使用它。
示例
@override
void didChangeDependencies()
final CounterBloc counterBloc = BlocProvider.of<CounterBloc>(context);
//do whatever you want with the bloc here.
super.didChangeDependencies();
【讨论】:
BlocProvider.ofdidChangeDependencies
中使用它。在父小部件中我有 BlocProvider
所以我可以访问子小部件中的块。每次我导航到特定视图时,我都会使用它来使用 counterBloc.add(...)
触发事件。
在 didChangeDependencies 中触发 bloc 事件是非常糟糕的做法 - 特别是检查在复杂的小部件中可以触发多少次。在这里使用上下文是安全的,但不一致。【参考方案2】:
问题是您正在 BlocProvider
内初始化 FileManagerBloc
的实例,这当然是父小部件无法访问的。我知道这有助于自动清理Bloc
,但如果你想在initState
或didChangeDependencies
中访问它,那么你必须像这样在父级初始化它,
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
上提供/初始化,那么它可以通过BlocProvider.of<CounterBloc>(context);
在this
级别轻松访问
【讨论】:
以上是关于如何在 initState 方法中访问颤振块?的主要内容,如果未能解决你的问题,请参考以下文章
在颤振中在 initstate() 之前调用了dependOnInheritedElement()