将mapEventToState与传入流一起使用的最佳实践?

时间:2019-11-26 11:04:06

标签: flutter design-patterns bloc

是否有任何优雅的方法可以直接在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 {

}

3 个答案:

答案 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 listenerDart/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)

构建另一个封装字节流的块。

您可以创建两个事件(ByteReadByteConsume)和两个状态(ByteWaitingByteAvailable)。

BytereadByteAvailable应该有一个_byte字段用于存储数据。您的bytebloc拥有一个订阅者,该订阅者正在侦听流,并且每次它读取一个字节时,都会触发ByteRead事件。

您还应该在块中添加consume()方法,该方法给出读取的最后一个字节并触发ByteConsume事件。

两个状态和事件是相互的:

  • 您从字节等待开始,每当您有ByteRead时,都将更改为ByteAvailable,并且
  • 每次有ByteConsume时,您都变回ByteWaiting