Bloc如何监听流并发出状态。

14
在我的Flutter应用中,我使用flutter_bloc进行状态管理。
所涉及的bloc使用一个repository。该repository订阅了一个WebSocket,新数据会添加到一个流中。
问题: 我的bloc监听这个流:
InvestmentClubBloc({
    required this.investmentClubRepository
  }) : super(InvestmentClubLoading()) {
    onChangeSubscription = investmentClubRepository.onNewMessage.listen(
      (event) {
        emit(NewMessageState(event); // <-- The member "emit" can only be used within 'package:bloc/src/bloc.dart' or in test
      },
    );
  }

问题在于emit无法使用(我收到了警告:"The member "emit" can only be used within 'package:bloc/src/bloc.dart' or in test")。
bloc如何监听流并根据流事件发出新状态?

你使用的 flutter_bloc 版本是哪个? - 聂超群
flutter_bloc: ^8.0.0 - Vingtoft
1
请检查下面的答案。 - 聂超群
谢谢你提出这个好问题。 - Shady Mohamed Sherif
2个回答

27
你应该在eventHandler中使用emit,使用以下代码完成你的任务:
abstract class Event {}

class DemoEvent extends Event {}

var fakeStream =
    Stream<int>.periodic(const Duration(seconds: 1), (x) => x).take(15);

class DemoBloc extends Bloc<Event, int> {
  DemoBloc() : super(0) {
    fakeStream.listen((_) {
      // add your event here
      add(DemoEvent());
    });
    on<DemoEvent>((_, emit) {
      // emit new state
      emit(state + 1);
    });
  }
}

2
澄清一下:即使我们在bloc中监听流,bloc也应该将事件添加到自身吗?我确实认为这个解决方案可以实现,但是它似乎有很多额外的代码。 - Vingtoft
2
代码基于您的用例。如果您有一个流,也许StreamBuilder可以满足您的要求,那么您就不需要bloc了。 - 聂超群
嘿,也许你能帮我解决这个问题吗?https://dev59.com/WsTsa4cB1Zd3GeqPCqsx - Marcel Dz
1
这确实提供了克服昨晚问题的逻辑,但是嘿,在听取部分,你肯定要使用 StreamBuilder,这就是我完成工作的方式。即使我还有另一个 bloc builder,所以逻辑是,我在 StreamBuilder 构建器属性中返回了 BlocBuilder,并在 if(snapshot.hasData) {... ...} 之间应用了我的流逻辑。 - ArifMustafa
3
不要忘记在“关闭”中取消订阅。 - MJ Studio

10

你应该使用 emit.forEach(),其中 forEach 必须返回将要被发射的状态。

像这样:

await emit.forEach(yourStream, onData: (dynamic coming_data) {
  return your_state;
}).catchError((error) {
  emit error;
});

嘿,也许你能在这里帮我一下吗?https://dev59.com/WsTsa4cB1Zd3GeqPCqsx - Marcel Dz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接