在一个简单的 BLoC 示例中使用 Streams/Sinks
Use of Streams/Sinks in a simple BLoC Example
我正在尝试理解一个应用程序的简单 BLoC 示例,该应用程序 increments/decrements 一个基于按钮的计数器(即默认的 Flutter 应用程序,添加了一个用于递减计数器的按钮)。
我无法理解为什么我们需要在 class 中管理三个 streams/sinks CounterBloc
:
StreamSink<int> get _inCounter => _counterStateController.sink;
Stream<int> get counter => _counterStateController.stream;
Sink<CounterEvent> get counterEventSink => _counterEventController.sink;
特别是,为什么我们需要 _inCounter
和 counter
的单独变量?
完整代码如下:
counter_event.dart
:
class IncrementEvent extends CounterEvent {}
class DecrementEvent extends CounterEvent {}
counter_bloc.dart
:
import 'package:flutter_bloc/counter_event.dart';
class CounterBloc {
int _counter = 0;
final _counterStateController = StreamController<int>();
StreamSink<int> get _inCounter => _counterStateController.sink;
Stream<int> get counter => _counterStateController.stream;
final _counterEventController = StreamController<CounterEvent>();
Sink<CounterEvent> get counterEventSink => _counterEventController.sink;
CounterBloc() {
_counterEventController.stream.listen(_mapEventToState);
}
_mapEventToState(CounterEvent event) {
if (event is IncrementEvent)
_counter++;
else
_counter--;
_inCounter.add(_counter);
}
void dispose() {
_counterStateController.close();
_counterEventController.close();
}
}
main.dart
的相关摘录:
class _MyHomePageState extends State<MyHomePage> {
final _bloc = CounterBloc();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: StreamBuilder(
stream: _bloc.counter,
initialData: 0,
builder: (BuildContext context, AsyncSnapshot snapshot) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'${snapshot.data}',
style: Theme.of(context).textTheme.headline4,
),
],
);
},
),
),```
首先你需要明白我们使用的是StreamController
,它基本上就像一个管道。您使用 sink
放置一个值,然后使用 stream
.
在另一端获得该值
我们将 _counterStateController
声明为 StreamController
以控制 _counter
值。无论您通过 _inCounter
传递什么值,您都将使用流 counter
获得该值
final _counterStateController = StreamController<int>();
StreamSink<int> get _inCounter => _counterStateController.sink;
Stream<int> get counter => _counterStateController.stream;
另一个接收器 counterEventSink
是 _counterEventController
StreamController 的接收器,您可以将其用于控制器 CounterEvent
、IncrementEvent 或 DecrementEvent。
final _counterEventController = StreamController<CounterEvent>();
Sink<CounterEvent> get counterEventSink => _counterEventController.sink;
无论您在接收器 _counterEventController
中放置什么值 counterEventSink
,您都将通过它的流获得该值,我们将在创建 CounterBloc
时收听该流对象。
CounterBloc() {
_counterEventController.stream.listen(_mapEventToState); //listening to the CounterEvent Stream
}
这里我们将 _mapEventToState
函数作为回调传递。每当您向 counterEventSink
.
中输入任何值时,都会调用此函数
在 _mapEventToState
中,我们只是检查传递的事件类型,然后将该值添加到 _inCounter
,即 _counterStateController
的流。因此,您添加到 _inCounter
的任何内容都将通过 counter
.
接收
_mapEventToState(CounterEvent event) {
if (event is IncrementEvent)
_counter++;
else
_counter--;
_inCounter.add(_counter);
}
我正在尝试理解一个应用程序的简单 BLoC 示例,该应用程序 increments/decrements 一个基于按钮的计数器(即默认的 Flutter 应用程序,添加了一个用于递减计数器的按钮)。
我无法理解为什么我们需要在 class 中管理三个 streams/sinks CounterBloc
:
StreamSink<int> get _inCounter => _counterStateController.sink;
Stream<int> get counter => _counterStateController.stream;
Sink<CounterEvent> get counterEventSink => _counterEventController.sink;
特别是,为什么我们需要 _inCounter
和 counter
的单独变量?
完整代码如下:
counter_event.dart
:
class IncrementEvent extends CounterEvent {}
class DecrementEvent extends CounterEvent {}
counter_bloc.dart
:
import 'package:flutter_bloc/counter_event.dart';
class CounterBloc {
int _counter = 0;
final _counterStateController = StreamController<int>();
StreamSink<int> get _inCounter => _counterStateController.sink;
Stream<int> get counter => _counterStateController.stream;
final _counterEventController = StreamController<CounterEvent>();
Sink<CounterEvent> get counterEventSink => _counterEventController.sink;
CounterBloc() {
_counterEventController.stream.listen(_mapEventToState);
}
_mapEventToState(CounterEvent event) {
if (event is IncrementEvent)
_counter++;
else
_counter--;
_inCounter.add(_counter);
}
void dispose() {
_counterStateController.close();
_counterEventController.close();
}
}
main.dart
的相关摘录:
class _MyHomePageState extends State<MyHomePage> {
final _bloc = CounterBloc();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: StreamBuilder(
stream: _bloc.counter,
initialData: 0,
builder: (BuildContext context, AsyncSnapshot snapshot) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'${snapshot.data}',
style: Theme.of(context).textTheme.headline4,
),
],
);
},
),
),```
首先你需要明白我们使用的是StreamController
,它基本上就像一个管道。您使用 sink
放置一个值,然后使用 stream
.
我们将 _counterStateController
声明为 StreamController
以控制 _counter
值。无论您通过 _inCounter
传递什么值,您都将使用流 counter
final _counterStateController = StreamController<int>();
StreamSink<int> get _inCounter => _counterStateController.sink;
Stream<int> get counter => _counterStateController.stream;
另一个接收器 counterEventSink
是 _counterEventController
StreamController 的接收器,您可以将其用于控制器 CounterEvent
、IncrementEvent 或 DecrementEvent。
final _counterEventController = StreamController<CounterEvent>();
Sink<CounterEvent> get counterEventSink => _counterEventController.sink;
无论您在接收器 _counterEventController
中放置什么值 counterEventSink
,您都将通过它的流获得该值,我们将在创建 CounterBloc
时收听该流对象。
CounterBloc() {
_counterEventController.stream.listen(_mapEventToState); //listening to the CounterEvent Stream
}
这里我们将 _mapEventToState
函数作为回调传递。每当您向 counterEventSink
.
在 _mapEventToState
中,我们只是检查传递的事件类型,然后将该值添加到 _inCounter
,即 _counterStateController
的流。因此,您添加到 _inCounter
的任何内容都将通过 counter
.
_mapEventToState(CounterEvent event) {
if (event is IncrementEvent)
_counter++;
else
_counter--;
_inCounter.add(_counter);
}