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 - 是不是可以在导航堆栈中为上一页产生状态?的主要内容,如果未能解决你的问题,请参考以下文章

React Native:从导航堆栈中删除后退按钮?

Bloc 模式是不是适合在 Flutter 应用中管理导航?

如何在 android studio 中为初学者添加操作栏?

Bloc:如何模拟获取状态

wordpress 如何在子页面中导航上一页和下一页

Nextjs如何在转到下一页时不卸载上一页(保持状态)