【问题标题】:how to reuse previous state fields in flutter bloc pattern?如何在颤动块模式中重用以前的状态字段?
【发布时间】:2020-04-09 12:18:30
【问题描述】:

有以下内容。使用sliding_up_panel,它的正文带有消息,并且在面板内容中具有不同的视图,该视图在底部栏的单击操作中弹出。

  @override
  Stream<AppState> mapEventToState(
    AppEvent event,
  ) async* {
    if (event is LoadChat) {
      List<Msg> msgs = await Api.getMessages();
      yield LoadedChat(messages: msgs);
    } else if (event is OrderPanelOpen) {
      yield OpenedPanelState();
    } else if (event is OrderPanelClose) {
      yield ClosedPanelState();
    }
  }

目标是在面板打开时隐藏 appBar。 appBar 存在于 AppLayout 中,它是父级,将 SlidingUpPanel 小部件本身保存在 Scaffold 中。

class _AppLayoutState extends State<AppLayout> {
  @override
  Widget build(BuildContext context) {
    var bloc = BlocProvider.of<AppBloc>(context);
    return Container(
      child: Scaffold(
        appBar: widget.showAppBar
            ? AppBar(...)
            : null,
        bottomNavigationBar: BottomAppBar(...),
        body: SlidingUpPanel(...),
      ),
    );
  }
}

following 是将面板事件添加到 bloc 的操作

 IconButton(
   icon: Icon(Icons.description),
   onPressed: () {
     if (widget.pannelCtrl.isPanelClosed()) {
       widget.pannelCtrl.open();
       bloc.add(OrderPanelOpen());
     } else {
       widget.pannelCtrl.close();
       bloc.add(OrderPanelClose());
     }
 })

这里的问题是 SlidingUpPanel 有一个主体需要显示消息,无论面板打开还是关闭。如果面板打开和关闭事件使用 bloc 映射到状态,则这些打开和关闭事件必须是单独的状态,但来自当前状态的消息必须通过构造函数参数传递到新状态或其他方式。是实现这一目标的正确方法,还是我在这里缺少其他更清洁的方法。

class ClosedPanelState implements LoadedChat {
  final messagesArg;
  ClosedPanelState({this.messagesArg});

  @override
  Widget get currentView => Chat(messages: this.messagesArg);

  @override
  List<Object> get props => [];

  @override
  bool get showAppBar => true;

  @override
  String get title => 'Order Food';

  @override
  List<Msg> get messages => messages;
}

【问题讨论】:

  • 你找到合适的解决方案了吗??

标签: flutter dart bloc


【解决方案1】:

根据您的问题标题,您可以做一件事。

对于您的 bloc 类,您可以创建一个类似堆栈的变量(您可以根据需要使用自己的 LIFO 堆栈实现或使用 List)。您的 bloc 类必须是 Singleton 才能保存事件。

static final List&lt;AppEvent&gt; _events = new List&lt;AppEvent&gt;();

然后在您的 _mapEventToState 实现中添加调用到变量的事件:

@override
  Stream<AppState> mapEventToState(
    AppEvent event,
  ) async* {
    _events.add(event); // New Line
    if (event is LoadChat) {
      List<Msg> msgs = await Api.getMessages();
      yield LoadedChat(messages: msgs);
    } else if (event is OrderPanelOpen) {
      yield OpenedPanelState();
    } else if (event is OrderPanelClose) {
      yield ClosedPanelState();
    }
  }

稍后你编写一个方法来调用堆栈/列表中的最后一个事件。

dispatchPreviousState() {
    this.add(_events.removeLast());
  }

这对我来说可以调用最新的事件并再次调度它。

【讨论】:

    猜你喜欢
    • 2021-08-13
    • 2021-04-19
    • 2021-09-25
    • 2019-03-28
    • 2022-11-16
    • 2011-01-09
    • 2019-08-28
    • 2023-01-16
    • 2013-07-18
    相关资源
    最近更新 更多