[英]how to access flutter bloc in the initState method?
In the code shown below, the dispatch event is called from within the build method after getting the BuildContext object. What if I wish to do is to dispatch an event during processing at the start of the page within the initState method itself?在下面显示的代码中,在获取 BuildContext object 后从构建方法中调用调度事件。如果我想做的是在 initState 方法本身的页面开始处理期间调度事件怎么办?
If I use didChangeDependencies method, then I am getting this error: BlocProvider.of() called with a context that does not contain a Bloc of type FileManagerBloc.
如果我使用 didChangeDependencies 方法,那么我会收到此错误:
BlocProvider.of() called with a context that does not contain a Bloc of type FileManagerBloc.
how to fix this?如何解决这个问题?
@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)) ;
});
}
The problem is that you are initializing the instance of FileManagerBloc
inside the BlocProvider
which is, of course inaccessible to the parent widget.问题是您正在
BlocProvider
内部初始化FileManagerBloc
的实例,这当然是父小部件无法访问的。 I know that helps with automatic cleanup of the Bloc
but if you want to access it inside initState
or didChangeDependencies
then you have to initialize it at the parent level like so,我知道这有助于自动清理
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)) ;
});
}
alternatively, if FileManagerBloc
was provided/initialized at a grandparent Widget
then it could easily be accessible at this
level through BlocProvider.of<CounterBloc>(context);
或者,如果
FileManagerBloc
是在祖父Widget
提供/初始化的,那么可以通过BlocProvider.of<CounterBloc>(context);
在this
级别轻松访问它BlocProvider.of<CounterBloc>(context);
Solution: Step 1: need apply singleton pattern on Bloc class解决方案:第一步:需要在Bloc class上应用singleton模式
class AuthBloc extends Bloc<AuthEvent, AuthState> {
static AuthBloc? _instance;
static AuthBloc get instance {
if (_instance == null) _instance = AuthBloc();
return _instance!;
}
....
....
Step 2: use AuthBloc.instance on main.dart for Provider第 2 步:使用 main.dart 上的 AuthBloc.instance 作为 Provider
void main() async {
runApp(MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => AuthBloc.instance,
),
...
...
],
child: App(),
));
}
Now you can use Bloc without context现在您可以在没有上下文的情况下使用 Bloc
you can use it in didChangeDependencies
method rather than initState
.您可以在
didChangeDependencies
方法而不是initState
使用它。
Example例子
@override
void didChangeDependencies() {
final CounterBloc counterBloc = BlocProvider.of<CounterBloc>(context);
//do whatever you want with the bloc here.
super.didChangeDependencies();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.