首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将BLoC的接收器连接到另一个BLoC

将BLoC的接收器连接到另一个BLoC
EN

Stack Overflow用户
提问于 2018-11-11 23:42:18
回答 2查看 2.4K关注 0票数 2

我使用的是BLoC模式,如谷歌IO的谈话中所描述的。

我有一个简单的BLoC,用于每当将字符串添加到messageSink时在UI中显示警报

代码语言:javascript
复制
class AlertBloc {
  final _message = BehaviorSubject<String>();

  AlertBloc() {}

  Stream<String> get message => _message.stream;

  Sink<String> get messageSink => _message.sink;

  void dispose() {
    _message.close();   }
}

在应用程序的其他地方,我有另一个BLoC,它需要在满足特定条件时向messageSink添加一个字符串。

我注意到从BLoC中提供整个谷歌I/O回购并不是一个好主意,他们为将从BLoC连接到另一个BLoC 接收器提供了建议。

请注意,我们并没有直接向CartBloc提供ProductSquareBloc,尽管它更容易实现。集团不应依赖其他集团(利益分离)。它们只能使用流进行通信。在本例中,CartBloc.items输出插件插入到ProductSquareBloc.cartItems输入中。

我的问题是如何将接收器从BLoC连接到另一个BLoC

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-08-19 15:31:18

下面是一个简单的例子。想象一下以下两个区块:

第一个公开一个Stream并使用一些值填充它:

代码语言:javascript
复制
class ProducerBLoC {

    //Controller is private - you do not want to expose it
    final StreamController<int> _productionController = StreamController<int>();
    //Instead, you expose a stream
    Stream<int> get production => _productionController.stream;

    //This method generates some values and puts them to stream
    void produceValue() {
        _productionController.sink.add(1);
        _productionController.sink.add(2);
        _productionController.sink.add(3);
    }

    //Don't forget to close your controllers
    void dispose() {
      _productionController.close();
    }
}

另一个则公开一个Sink并处理放入其中的值。

代码语言:javascript
复制
class ConsumerBLoC {

    //Controller is private - you do not want to expose it
    final StreamController<int> _consumptionController = StreamController<int>();
    //Instead, you expose a sink
    StreamSink<int> get consumption => _consumptionController.sink;

    //In class constructor we start listening to the stream of values
    ConsumerBLoC() {
       _consumptionController.listen((value) {_consumeValue(value);} );
       //or simply: _consumptionController.listen(_consumeValue); //theese are the same
    }

    //This method generates some values and puts them to stream
    void consumeValue(int value) {
         //Do something with the value
         print('Value processed: $value');
    }

    //Don't forget to close your controllers
    void dispose() {
      _consumptionController.close();
    }
}

现在,任务是将生产流与消费汇连接起来。正如您正确地注意到的,您不希望两个组中的任何一个知道另一个组的存在。因此,两者都不应该保存对另一个的引用,甚至不应该创建另一个实例。相反,您可以使用Widget类连接它们:

代码语言:javascript
复制
//Define some widget to represent main screen of your application
class MainScreen extends StatefulWidget {

   @override
   State<StatefulWidget> createState() => _MainScreenState();
}

//And define a state for this widget (state does not need to be public)
class _MainScreenState extends State<MainScreen> {

    //You define both blocks here
    ProducerBLoC _producer = new ProducerBLoC();
    ConsumerBLoC _consumer = new ConsumerBLoC();

    //Now, either do it in _MainScreenState constructor, or in the initState() method
    @override
    void initState() {
        super.initState();

        //Connect production stream with consumption sink
        _producer.production.listen((value) => _consumer.consumption.add(value));
        //Or, beautifully: _producer.production.pipe(_consumer.consumption);
    }

    @override
    Widget build(BuildContext context) {
        //The exact implementation does not matter in current context
    }

    //And don't forget to close your controllers
    @override
    dispose() {
        super.dispose();
        _producer.dispose();
        _consumer.dispose();
    }

}

这样,ProducerBLoC生成的任何值都将立即由ConsumerBLoC使用。而且,最重要的是,这两个集团完全独立于彼此!

票数 4
EN

Stack Overflow用户

发布于 2018-11-12 01:27:16

与处理流的方式完全相同:将其作为参数传递

代码语言:javascript
复制
class Bloc {
  final Sink<int> _external;

  Bloc(this._external);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53254371

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档