【问题标题】:How to listen to multiple stream subscriptions in a bloc?如何在一个块中收听多个流订阅?
【发布时间】:2021-07-17 18:56:29
【问题描述】:

我正在尝试创建一个依赖于其他两个集团的集团。例如,我有Bloc C,它依赖于Bloc ABloc B。我正在尝试使用flutter_bloc 执行以下操作以实现它:

class BlocC
    extends Bloc< BlocCEvent, BlocCState> {
  final BlocA blocA;
  final BlocC blocB;

  StreamSubscription blocASubscription;
  StreamSubscription blocBSubscription;

  BlocC({
    @required this.blocA,
    @required this.blocB,
  }) : super((blocA.state is blocALoaded &&
                blocB.state is blocBLoaded)
            ? BlocCLoaded(
                blocA: (blocA.state as blocALoaded).arrayFromBlocA,
                blocB:
                    (blocB.state as blocBLoaded).arrayFromBlocB,
              )
            : BlocCLoading()) {
              
    blocASubscription = blocA.stream.listen((state) {
      if (state is blocALoaded) {
        add(BlocAUpdated((blocA.state as blocALoaded).arrayFromBlocA));
      }
    });

    blocBSubscription = blocB.stream.listen((state) {
      if (state is BlocBLoaded) {
        add(BlocBUpdated((blocB.state as BlocBLoaded).arrayFromBlocB));
      }
    });
  }

  ...

  @override
  Future<void> close() {
    blocASubscription.cancel();
    BlocBSubscription.cancel();
    return super.close();
  }
}

问题是我收到以下错误:Bad state: Stream has already been listened to。我在下一个post 中找到了有关该错误的信息。

我了解错误正在发生,因为流一次只能听一个 bloc,而不能听多个 bloc。就我而言,当我尝试收听blocB 时,流已经在收听blocA。但是,我不确定如何解决此问题。

我将非常感谢任何帮助。

【问题讨论】:

    标签: flutter flutter-bloc


    【解决方案1】:

    您必须将两个流合并为一个并根据事件类型采取行动:

    import 'package:async/async.dart' show StreamGroup;
    
    //...
    
    final blocAStream = blocA.stream;
    final blocBStream = blocB.stream;
    var blocAandBStreams = StreamGroup.merge([blocAStream, blocBStream]);
    
    blocAandBStream.listen((event){
      if(event is BlocAState){
        if (event is blocALoaded) { //<-- for readability
          add(BlocAUpdated((blocA.state as blocALoaded).arrayFromBlocA));
        }
      }else if(event is BlocBState){
        if (event is BlocBLoaded) {//<-- for readability
          add(BlocBUpdated((blocB.state as BlocBLoaded).arrayFromBlocB));
        }
      }
    })
    
    

    【讨论】:

      【解决方案2】:

      我已经实现了事件总线模式来在块之间进行通信。这种方法的优点是您的块实例不会相互耦合,因此您不需要 实例化或注入他们的实例Manage Global Events by bloc

      【讨论】:

        猜你喜欢
        • 2020-02-13
        • 2019-01-22
        • 2017-01-20
        • 1970-01-01
        • 1970-01-01
        • 2019-08-09
        • 1970-01-01
        • 2019-02-28
        • 1970-01-01
        相关资源
        最近更新 更多