Bloc - 是不是可以在导航堆栈中为上一页产生状态?
Posted
技术标签:
【中文标题】Bloc - 是不是可以在导航堆栈中为上一页产生状态?【英文标题】:Bloc - Is it possible to yield states for a previous page in the navigation stack?Bloc - 是否可以在导航堆栈中为上一页产生状态? 【发布时间】:2021-01-28 06:11:09 【问题描述】:我有一个 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();
【问题讨论】:
【参考方案1】:与其尝试改变另一个页面的状态(在状态管理方面有点禁忌),不如利用导航器的push
方法返回一个在该页面被弹出时完成的future ,并且作为奖励,future 的值将包括在另一页中提供给 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(...);
注意:这也适用于命名路由。
【讨论】:
看来这正是我所追求的。明天晚上我会试一试,一旦它起作用,就会接受你的回答。谢谢! 完美运行。再次感谢。以上是关于Bloc - 是不是可以在导航堆栈中为上一页产生状态?的主要内容,如果未能解决你的问题,请参考以下文章
Bloc 模式是不是适合在 Flutter 应用中管理导航?