屏幕加载时如何仅调用一次 bloc 事件
Posted
技术标签:
【中文标题】屏幕加载时如何仅调用一次 bloc 事件【英文标题】:How to call bloc event only once when the screen loads 【发布时间】:2020-12-10 23:43:45 【问题描述】:我正在使用flutter_bloc 库。我的屏幕小部件代码如下所示:
class RegisterScreen extends StatefulWidget
RegisterScreen();
@override
_RegisterScreenState createState() => _RegisterScreenState();
class _RegisterScreenState extends State<RegisterScreen>
@override
Widget build(BuildContext context)
return BlocProvider<RegisterBloc>(
create: (BuildContext context)
// RegisterBloc.get(context).add(RegisterGetCitiesEvent());<=== This gives me error `BlocProvider.of() called with a context that does not contain a Cubit of type RegisterBloc. \n No ancestor could be found starting from the context that was passed to BlocProvider.of<RegisterBloc>().`
return RegisterBloc();
,
child: BlocConsumer<RegisterBloc, RegisterState>(
listener: (BuildContext context, RegisterState state) ,
builder: (BuildContext context, RegisterState state)
// RegisterBloc.get(context).add(RegisterGetCitiesEvent());<=== This line is executed infinite times
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: ()
RegisterBloc.get(context).add(RegisterGetCitiesEvent());
,
child: new Icon(Icons.refresh),
),
body: Conteiner(
child: Text(RegisterBloc.get(context).cities==null?'':RegisterBloc.get(context).cities,)
),
);
,
),
);
而bloc
文件是这样的:
class RegisterBloc extends Bloc<RegisterEvent, RegisterState>
static RegisterBloc get(BuildContext context) => BlocProvider.of(context);
RegisterBloc() : super(RegisterInitial());
String cities = '';
@override
Stream<RegisterState> mapEventToState(
RegisterEvent event,
) async*
if (event is RegisterGetCitiesEvent)
yield* getCities();
Stream<RegisterGetCitiesState> getCities() async*
yield await (CustomerServer.getCities()).then((res)
cities = res;
return RegisterGetCitiesState();
);
在我的代码中,我必须点击FAB
来调用RegisterGetCitiesEvent
bloc 事件。如何在不要求用户单击任何按钮的情况下立即调用该事件RegisterBloc.get(context).add(RegisterGetCitiesEvent())
?
我尝试了什么:
我尝试在 BlocConsumer
构建器函数中添加该行,但该函数执行了无限次。
我试图在BlocProvider
创建函数中添加该行,但它给了我一个错误BlocProvider.of() called with a context that does not contain a Cubit of type RegisterBloc.
我应该把这行RegisterBloc.get(context).add(RegisterGetCitiesEvent())
放在哪里,以便在屏幕显示时自动调用RegisterGetCitiesEvent
事件(无需点击任何按钮)?
【问题讨论】:
【参考方案1】:我建议您完整阅读BLoC 文档。但这里是对这个问题的快速回答:您应该在BlocProvider
的创建函数中这样做。像这样:
class RegisterScreen extends StatefulWidget
RegisterScreen();
@override
_RegisterScreenState createState() => _RegisterScreenState();
class _RegisterScreenState extends State<RegisterScreen>
@override
Widget build(BuildContext context)
return BlocProvider<RegisterBloc>(
create: (context) => RegisterBloc()..add(RegisterGetCitiesEvent())
);
【讨论】:
谢谢@Amir_P,在上面的例子中,RegisterGetCitiesEvent()
事件是否会在每次将这个RegisterScreen
推送到导航堆栈时触发?
是的,它会被称为@Mikethetechy以上是关于屏幕加载时如何仅调用一次 bloc 事件的主要内容,如果未能解决你的问题,请参考以下文章
Flutter BLoC mapEventToState 仅在事件的第一次调用时才被调用,并且不会在下次触发该事件时调用