我使用的是BLoC模式,如谷歌IO的谈话中所描述的。
我有一个简单的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(); }
}在应用程序的其他地方,我有另一个BLoC,它需要在满足特定条件时向messageSink添加一个字符串。
我注意到从BLoC中提供整个谷歌I/O回购并不是一个好主意,他们为将流从BLoC连接到另一个BLoC 接收器提供了建议。
请注意,我们并没有直接向CartBloc提供ProductSquareBloc,尽管它更容易实现。集团不应依赖其他集团(利益分离)。它们只能使用流进行通信。在本例中,CartBloc.items输出插件插入到ProductSquareBloc.cartItems输入中。
我的问题是如何将接收器从BLoC连接到另一个BLoC 流。
发布于 2019-08-19 15:31:18
下面是一个简单的例子。想象一下以下两个区块:
第一个公开一个Stream并使用一些值填充它:
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并处理放入其中的值。
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类连接它们:
//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使用。而且,最重要的是,这两个集团完全独立于彼此!
发布于 2018-11-12 01:27:16
与处理流的方式完全相同:将其作为参数传递
class Bloc {
final Sink<int> _external;
Bloc(this._external);
}https://stackoverflow.com/questions/53254371
复制相似问题