flutter - Bloc - 是否可以在导航堆栈中为上一页产生状态?
问题描述
我有一个 BlocBuilder,它根据仪表板页面的生成状态处理构建小部件。
body: BlocBuilder<DashboardBloc, DashboardState>(
builder: (context, state) {
print(state);
if (state is DashboardInitial) {
return loadingList();
} else if (state is DashboardEmpty) {
return emptyList();
} else if (state is DashboardLoaded) {
return loadedList(context, state);
}
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => AddPage()));
},
我希望能够导航到添加页面,填写一些文本字段,然后将事件发送到我的仪表板块,其想法是在导航回仪表板时,我的列表将被更新。
class AddPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
TextEditingController titleController = TextEditingController();
TextEditingController descriptionController = TextEditingController();
return Scaffold(
appBar: AppBar(title: Text('Add')),
body: Container(
padding: EdgeInsets.all(10),
child: Column(
children: [
TextField(
controller: titleController,
),
TextField(
controller: descriptionController,
),
RaisedButton(onPressed: () {
BlocProvider.of<DashboardBloc>(context)
.add(DashboardWorryAdded('title', 'description'));
}),
],
),
),
);
}
}
当使用断点跟踪代码时,我可以看到我的状态是在“mapeventtostate”函数中产生的,但是我的仪表板永远不会用新值重建。
这是我的 Bloc、事件和状态的代码。我的第一个想法是 Equatable 正在检测返回相同的状态,但是在删除 Equatable 后,我的问题仍然存在。
@override
Stream<DashboardState> mapEventToState(
DashboardEvent event,
) async* {
if (event is DashboardWorryAdded) {
yield* _mapDashboardWorryAddedToState(event);
} else if (event is DashboardLoading) {
yield* _mapDashboardLoadingToState(event);
} else if (event is AppStarted) {
yield* _mapAppStartedToState(event);
}
}
Stream<DashboardState> _mapAppStartedToState(AppStarted event) async* {
List<Worry> _wList = await repo.getAllWorries();
if (_wList.length != 0) {
yield DashboardLoaded(worryList: _wList);
} else {
yield DashboardEmpty();
}
}
Stream<DashboardState> _mapDashboardLoadingToState(
DashboardLoading event) async* {
List<Worry> _wList = await repo.getAllWorries();
if (_wList != 0) {
yield DashboardLoaded(worryList: _wList);
} else {
yield DashboardEmpty();
}
}
Stream<DashboardState> _mapDashboardWorryAddedToState(
DashboardWorryAdded event) async* {
await repo.addWorry(event.title, event.description);
List<Worry> worryList = List<Worry>();
worryList = await repo.getAllWorries();
yield DashboardLoaded(worryList: worryList);
}
}
@immutable
abstract class DashboardEvent {}
class DashboardLoading extends DashboardEvent {
DashboardLoading();
}
class DashboardWorryAdded extends DashboardEvent {
final String title, description;
DashboardWorryAdded(this.title, this.description);
}
class AppStarted extends DashboardEvent {
AppStarted();
}
@immutable
abstract class DashboardState {}
class DashboardInitial extends DashboardState {
DashboardInitial();
}
class DashboardLoaded extends DashboardState {
final List<Worry> worryList;
DashboardLoaded({this.worryList});
}
class DashboardEmpty extends DashboardState {
DashboardEmpty();
}
解决方案
与其试图改变另一个页面的状态(在状态管理方面有点禁忌)push
,不如利用导航器的方法返回一个在该页面弹出时完成的未来,作为奖励,未来的值将包括pop
在另一页中赋予该方法的值。所以你现在可以做这样的事情:
class DashboardBloc {
...
void showAddPage() async {
// Do this to retrieve the value passed to the add page's call to `pop`
final value = await Navigator.of(context).push(...);
// Do this if the add page doesn't return a value in `pop`
await Navigator.of(context).push(...);
// Either way, you can now refresh your state in response to
// the add page popping
emit(...);
}
}
注意:这也适用于命名路由。
推荐阅读
- reactjs - 持续构建反应应用程序的开发版本以进行开发
- laravel - Vue vform 文件上传
- excel - Excel - VLOOKUP 公式的问题 - 它不选择日期
- hyperledger-fabric - eventthub 的 Hyperledger Fabric 错误:未实现:未知服务原型。交付
- macos - 如何将下载的文件(音频、文档)自动保存到 mac os x 沙盒应用程序中用户的下载文件夹?
- docker - 无法在 Ambari UI 中获取 HDP 公共回购
- java - spring data 如何在事务方法中清理持久化的实体?
- javascript - 如何确定从多个模态中打开哪个模态?
- c# - 使用 C# 如何将文本文件拆分为多个文件
- python - 分组并减去熊猫中的第一次出现和最后一次出现