是否有任何优雅的方法可以直接在mapEventToState()内部映射来自私有api的传入流,而不必在集团中创建多余的私有事件?
我提出了这个解决方案。一个单一的流没关系,但是有多个流就开始变得一团糟。预先感谢。
// (don't mind the imports, this is the bloc file)
class ExampleBloc extends Bloc<ExampleEvent, ExampleState> {
final MyPrivateApi api = MyPrivateApi.instance; // singleton
ExampleBloc() {
// api has a stream of booleans
api.myStream.listen((b) {
// if it's true fire this event
if (b) this.add(_MyPrivateEvent());
}
@override
ExampleState get initialState => InitialExampleState();
@override
Stream<ExampleState> mapEventToState(
ExampleEvent event,
) async* {
if (event is _MyPrivateEvent) {
yield SomeState;
}
}
// private Event
class _MyPrivateEvent extends ExampleEvent {
}
答案 0 :(得分:0)
如我所见,您可以在屏幕上订阅事件更新,如果需要一些计算,可以将事件从屏幕推送到Bloc。代码会更干净。
答案 1 :(得分:0)
您的方法似乎是唯一可行的方法,并且似乎已被使用-请参阅以下团体问题:https://github.com/felangel/bloc/issues/112和本示例项目:https://github.com/algirdasmac/streams_and_blocs
只需确保dispose
退回api.myStream.listen
的订阅。
上一个答案
以下不不适用于无限流,因为生成器函数将await
直到流结束。这仅可用于快速流式传输,例如上载/下载进度。
在Dart yield stream events from another stream listener和Dart/Flutter - "yield" inside a callback function
ExampleBloc() {
_MyInitEvent();
}
@override
Stream<ExampleState> mapEventToState(
ExampleEvent event,
) async* {
if (event is _MyInitEvent) {
await for (bool b in api.myStream) {
if (b) yield SomeState;
}
}
}
答案 2 :(得分:0)
构建另一个封装字节流的块。
您可以创建两个事件(ByteRead
和ByteConsume
)和两个状态(ByteWaiting
和ByteAvailable
)。
Byteread
和ByteAvailable
应该有一个_byte
字段用于存储数据。您的bytebloc拥有一个订阅者,该订阅者正在侦听流,并且每次它读取一个字节时,都会触发ByteRead
事件。
您还应该在块中添加consume()
方法,该方法给出读取的最后一个字节并触发ByteConsume
事件。
两个状态和事件是相互的:
ByteRead
时,都将更改为ByteAvailable
,并且ByteConsume
时,您都变回ByteWaiting
。