【发布时间】:2020-05-14 17:48:40
【问题描述】:
我有一个main.dart 有自己的main_bloc.dart、main_event.dart 和main_state.dart:
main_event:
- AppStarted
- GoingHome
- GoingTestHome
main_State:
- StateHome
- StateTestHome
main_bloc:
Stream<MainState> mapEventToState(
MainEvent event,
) async* {
if (event is AppStarted) {
print('mainbloc: AppStarted');
dispatch(GoingHome());
}
if (event is GoingHome) {
print('mainbloc: GoingHome');
yield StateHome();
}
if (event is TestHome) {
print('mainbloc: TestHome');
yield StateTestHome();
}
...
}
在我的main.dart:
class _AppState extends State<App> {
MainBloc _mainBloc;
@override
void initState() {
super.initState();
_mainBloc = MainBloc();
_mainBloc.dispatch(AppStarted());/// <-- 1
}
...
@override
Widget build(BuildContext context) {
return BlocProvider(
builder: (_) => _mainBloc,
child: MaterialApp(
title: 'Home',
theme: ThemeData(
...
),
home: BlocListener<MainBloc, MainState>(
bloc: _mainBloc,
listener: (context, state) {
print('state changed: ${state.toString()}');
if (state is StateHome) { /// <-- 2
print('main: StateHome');
_mainBloc.dispatch(TestHome()); /// <-- 2.1
} else if (state is StateTestHome) { /// <-- 3
print('main: StateTestHome');
}
},
child: SplashPage()),
...
我做一个快速测试:
- 应用启动时,调用
_mainBloc.dispatch(AppStarted()),会从main_bloc调用dispatch(GoingHome())。 -
BlocListener检测到状态变化('StateHome'),所以:print('main: StateHome'); _mainBloc.dispatch(TestHome()); -
BlocListener再次检测到状态变化('StateTestHome'),所以:print('main: StateTestHome');
在控制台中,我可以依次看到所有的打印信息:
Restarted application in 1,612ms.
I/flutter (15369): mainbloc: AppStarted
I/flutter (15369): mainbloc: GoingHome
I/flutter (15369): state changed: StateHome
I/flutter (15369): main: StateHome
I/flutter (15369): mainbloc: TestHome
I/flutter (15369): state changed: StateTestHome
I/flutter (15369): main: StateTestHome
到目前为止,它按我预期的方式运行。
但是当我取出代码2.1,然后添加一个按钮来触发事件:
...
floatingActionButton: FloatingActionButton(
child: Text('test'),
onPressed: () {
_mainBloc.dispatch(TestHome());
},
),
...
我会得到这样的控制台:
Restarted application in 2,738ms.
I/flutter (15369): mainbloc: AppStarted
I/flutter (15369): mainbloc: GoingHome
I/flutter (15369): state changed: StateHome
I/flutter (15369): main: StateHome
I/flutter (15369):
I/flutter (15369): mainbloc: TestHome ///<-- button trigger
我希望:
Restarted application in 2,738ms.
I/flutter (15369): mainbloc: AppStarted
I/flutter (15369): mainbloc: GoingHome
I/flutter (15369): state changed: StateHome
I/flutter (15369): main: StateHome
I/flutter (15369):
I/flutter (15369): mainbloc: TestHome ///<-- button trigger
I/flutter (15369): state changed: StateTestHome ///<-- expectation
I/flutter (15369): main: StateTestHome ///<-- expectation
似乎按钮交互没有yield 状态,或者BlocListener 没有捕获状态更改事件。
我在这里缺少什么?我该如何解决这个问题?
【问题讨论】:
-
据我所知
init()在build()之前触发,因此您在小部件树完全构建之前调度您的事件。试试这个:builder: (_) => _mainBloc.dispatch(AppStarted()),在build()func -
你知道
BlocDelegate吗?你可以用它来观察states和events,你可以释放一些print:P