flutter - 添加事件不会更新 BlocBuilder
问题描述
flutter_bloc
当页面第一次加载时,我正在使用该模式进行 api 调用。我正在添加事件,initState
一切正常。我也在尝试添加一个刷新按钮。我做的事情和我在initState
. 但它不会触发blocBuilder
. 这是表示层。
class OtherPage extends StatefulWidget {
@override
_OtherPageState createState() => _OtherPageState();
}
class _OtherPageState extends State<OtherPage> {
EngageBloc engageBloc;
int count = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: <Widget>[
IconButton(
icon: Icon(Icons.refresh),
onPressed: () {
engageBloc.add(FetchEngageEvent());
},
),
],
),
body: BlocBuilder<EngageBloc, EngageState>(builder: (context, state) {
if (state is EngageInitialState) {
return CircularProgressIndicator();
}
if (state is EngageLoadingState) {
return CircularProgressIndicator();
}
if (state is EngageLoadedState) {
final courses = state.courses;
return buildUi(courses);
}
if (state is EngageErrorState) {
return buildErrorUi(state.message);
}
return Container();
}));
}
Widget buildLoading() {
return Center(
child: CircularProgressIndicator(),
);
}
Widget buildErrorUi(String message) {
return Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
message,
style: TextStyle(color: Colors.red),
),
),
);
}
Widget buildUi(AvailableCourseBoxset courses) {
return Text('It works!!');
}
@override
void initState() {
engageBloc = BlocProvider.of<EngageBloc>(context);
engageBloc.add(FetchEngageEvent());
super.initState();
}
}
有什么明显的我做错了。当我单击刷新按钮时,会进行 api 调用。日志中没有出现错误。我正在使用跟踪状态转换的观察者。输出:
flutter: onTransition Transition { currentState: EngageLoadedState, event: FetchEngageEvent, nextState: EngageLoadingState }
flutter: onTransition Transition { currentState: EngageLoadingState, event: FetchEngageEvent, nextState: EngageLoadedState
}
EngageLoadingState 被调用,但 ui 甚至没有为此更新。正如我所说的 initState 有效,但对刷新按钮执行相同操作却没有。我很感激我可能需要添加更多代码......只要问,我会发布你的要求......谢谢。
解决方案
您不应该将 bloc 类存储在变量中。您应该为它提供一个BlocProvider
然后使用它BlocProvider.of<EngageBloc>(context).add(FetchEngageEvent());
来添加这个块的事件。
这是因为可以在整个应用程序中设置不同的块,因此您希望使用提供者/消费者模型来管理它们。
为了使其工作,您尽管必须将 BlocProvider 放在您的 Scaffold 之前,以便能够在您的 appBar 中访问它。
推荐阅读
- php - 在发送到 php 中的客户端之前压缩 blob 图像文件
- amazon-web-services - AWS AMI:从仿生配置 AMI 时需要显式删除 apt 锁
- php - Cakephp 3.6.14:在控制器中为视图中的选择框进行选择并禁用它
- c++ - 在 Windows 上使用 WinSSL 构建静态 libcurl 库
- python - Python中随机包代码的问题
- javascript - 为什么 cancelledPromise 模式被认为比 React 中的 isMounted() “反模式”更好?
- excel - 获取“无法获取 WorksheetFunction 类的匹配属性”错误
- postgresql - 如何从 Grafana 的数据库中选择 DISTINCT 记录
- android - 在 onResume 中使用处理程序检查服务状态
- xml - 将 XML 转换为 CSV 时获取空 CSV