Dart 将一组水槽连接到另一组水槽

Dart 将一组水槽连接到另一组水槽,dart,flutter,Dart,Flutter,我正在使用中描述的集团模式 我有一个简单的BLoC,用于在向messageSink添加字符串时在UI中显示警报: class AlertBloc { final _message = BehaviorSubject<String>(); AlertBloc() {} Stream<String> get message => _message.stream; Sink<String> get messageSink => _m

我正在使用中描述的集团模式

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

class AlertBloc {
  final _message = BehaviorSubject<String>();

  AlertBloc() {}

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

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

  void dispose() {
    _message.close();   }
}
class-AlertBloc{
最终消息=行为主体();
AlertBloc(){}
Stream get message=>\u message.Stream;
Sink get messageSink=>\u message.Sink;
无效处置(){
_message.close();}
}
在应用程序的其他地方,我有另一个BLoC,当满足某个条件时,它需要向
messageSink
添加一个字符串

我注意到从提供整个组不是一个好主意,他们提供了将一个流从一个组连接到另一个的建议:

请注意,我们没有向客户提供[CartBloc] [ProductSquareBloc]直接,尽管这样更容易 使生效集团不应依赖于其他集团(集团分离) 关注)。他们只能使用 溪流。在这种情况下,[CartBloc.items]输出插入到 [ProductSquareBloc.cartItems]输入


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

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

class Bloc {
  final Sink<int> _external;

  Bloc(this._external);
}
class集团{
最终水槽(外部);
集团(本集团外部);
}

以下是一个简单的示例。想象一下以下两个集团:

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

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();
    }
}
现在,任务是将生产流连接到消费接收器。正如你们已经正确地注意到的,你们不想让两个集团中的任何一个知道关于另一个集团存在的任何事情。因此,这两种方法都不应该持有对另一种方法的引用,甚至不应该创建另一种方法的实例。相反,您可以使用
小部件
类连接它们:

//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();
    }

}
//定义一些小部件来表示应用程序的主屏幕
类MainScreen扩展StatefulWidget{
@凌驾
State createState()=>\u MainScreenState();
}
//并定义此小部件的状态(状态不需要是公共的)
类_MainScreenState扩展状态{
//在这里定义两个块
ProducerBLoC_producer=新ProducerBLoC();
ConsumerBLoC_consumer=新ConsumerBLoC();
//现在,要么在_MainScreenState构造函数中执行,要么在initState()方法中执行
@凌驾
void initState(){
super.initState();
//将生产流与消费水槽连接起来
_生产者.生产.收听((价值)=>_消费者.消费.增加(价值));
//或者,漂亮地说:_producer.production.pipe(_consumer.consumption);
}
@凌驾
小部件构建(构建上下文){
//在当前上下文中,具体的实现并不重要
}
//别忘了关闭控制器
@凌驾
处置{
super.dispose();
_producer.dispose();
_consumer.dispose();
}
}

这样,
ProducerBLoC
生成的任何值都将立即被
ConsumerBLoC
消耗。而且,最重要的是,-两个集团彼此完全独立

这不是一件好事。
Bloc
最好公开自己的
值,而不是抓住其他人的
接收器
并将值放入其中。
//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();
    }

}