【问题标题】:Is it possible listen state of many BloC?是否有可能监听许多 BloC 的状态?
【发布时间】:2019-11-26 13:07:22
【问题描述】:

在询问了 Flutter (Difference between ChangeNotifierProvider and ScopedModel in Flutter) 中的状态管理后没有任何答案,我决定使用 BLoC Package,这在我看来是最清晰和最容易使用的。 现在在我的颤振应用程序中,我有 BlocA、BlocB 和 BlocC,我想从 BlocC 监听 BlocA 和 BlocB 的状态变化。

在所有区块上具有相同状态/事件的示例(更新、更新/更新):

class BlocC extends Bloc<CEvent, CState> {
  final BlocA a;
  final BlocB b;
  StreamSubscription aSubscription;

  BlocC({@required this.a, @required this.b}) {
    aSubscription = a.state.listen((state) {
      if (state is AUpdated) {
        dispatch(UpdateC());
      }
    });
  }

  @override
  CState get initialState => CUpdating();

  @override
  Stream<CState> mapEventToState(CEvent event) async* {
    if (event is UpdateC && b.currentState is BUpdated) {
      yield* CUpdated();
    }
  }
...

在这种情况下,当从 BlocA 状态分派事件时,BlocB 的状态有时不会在 _mapEventToState 方法中更新,并且我的侦听器不起作用。 所以我认为有一种方法可以将一个块订阅到许多流,以获得所有流的正确状态转换。

你能帮帮我吗?

【问题讨论】:

    标签: flutter dart bloc


    【解决方案1】:

    这是预期的行为,因为您仅在BlocA 的状态为AUpdated 时调度UpdateC(),而不是在BlocB 的状态为BUpdated 时调度。

    即使你的调度事件同时改变了BlocABlocB 的状态,这也是异步的,所以你不能保证event is UpdateC &amp;&amp; b.currentState is BUpdated 永远是真的。所以你丢失了一些 UpdateC 事件。

    对于您的情况,您可以使用 rxdart 的combineLastest2。并且仅当BlocABlocB 同时具有Updated 状态时才调度UpdateC()

    import 'package:rxdart/rxdart.dart';
    
    class BlocC extends Bloc<CEvent, CState> {
      final BlocA a;
      final BlocB b;
      StreamSubscription<bool> _canUpdateCSubscription;
    
      BlocC({@required this.a, @required this.b}) {
        _canUpdateCSubscription = Observable.combineLatest2(
          a.state,
          b.state,
          (aState, bState) => aState is AUpdated && bState is BUpdated,
        ).listen(
          (canUpdateC) {
            if (canUpdateC) dispatch(UpdateC());
          },
        );
      }
    
      @override
      void dispose() {
        _canUpdateCSubscription?.cancel();
        _canUpdateCSubscription = null;
        super.dispose();
      }
    
      @override
      CState get initialState => CUpdating();
    
      @override
      Stream<CState> mapEventToState(CEvent event) async* {
        if (event is UpdateC) {
          yield* CUpdated();
        }
      }
    ...
    

    【讨论】:

    • 很好的解决方案!但最后我决定订阅 BlocB 到 BlocA 状态的调度。所以我有一个级联流。
    猜你喜欢
    • 2020-03-26
    • 2021-02-17
    • 2020-04-29
    • 2019-11-12
    • 2020-03-27
    • 2020-06-15
    • 2022-10-23
    • 2019-10-24
    • 2012-03-15
    相关资源
    最近更新 更多