[英]Flutter Bloc to Bloc Communication: How to receive data on initial listen to broadcast stream?
问题摘要:当我创建一个新的 bloc 时,我试图从 BlocA 的 StateA 中获取一个列表。
简化背景:我有一个总体块 (BlocA),它在此问题的上下文中始终处于活动状态,以及 2 个屏幕,每个屏幕都有一个相应的块 (BlocB 和 BlocC),在路由到其关联屏幕时创建并在路由离开时关闭从其关联的屏幕。 每次创建一个新的 bloc 时,它都需要从 BlocA 的状态中获取其数据。 用户可能会在屏幕之间来回移动。
我尝试了什么:我在 BlocA 中创建了流控制器,通过 getter 将相关数据流式传输到每个 bloc。 起初,我尝试了一个正常的(单监听器)流,它最初运行良好。 但是,当路由离开然后返回屏幕时,使用 getter 重新订阅同一流时会引发错误。 然后我将流控制器实例化为广播流StreamController.broadcast()
。 那么问题是,当订阅流时,订阅流时不会像普通流一样传递任何数据,当我尝试在广播构造函数中实现 onListen 回调时(将事件添加到接收器)它给出我的错误The instance member '_aStream' can't be accessed in an initializer
。 状态出现类似的错误。 见下文:
... _aStream = StreamController.broadcast(onListen: () {return _aStream.add(state.TypeX)})
简化示例代码:
class BlocA extends Bloc<BlocAEvent, BlocAState> {
BlocA() : super(BlocAState()) {
on<EventA>(_onevent);
}
final StreamController<TypeX> _aStream = StreamController.broadcast();
Stream<TypeX> get aStream => _aStream.stream;
final StreamController<TypeY> _bStream = StreamController.broadcast();
Stream<TypeY> get bStream => _bStream.stream;
...
// sink.add()'s are implemented in events
}
class BlocB extends Bloc<BlocBEvent, BlocBState> {
BlocB({required this.blocA}) : super(BlocBState()) {
on<EventB>(_onEventB);
blocASubscription = blocA.aStream.listen((stream) {
if (stream != state.fieldX) {
add(EventB(fieldX: stream));
}
});
}
final BlocA blocA
late final StreamSubscription blocASubscription;
FutureOr<void> _onEventB(EventB event, Emitter<BlocBState> emit) {
emit(state.copyWith(fieldX: event.fieldX));
}
}
class BlocC extends Bloc<BlocCEvent, BlocCState> {
// similar to BlocB
}
您不需要流,因为 bloc underhood 还在流中。 你可以通过事件和状态发送你想要的一切。 查看 Angelov 的库https://bloclibrary.dev/#/
我最终还是使用了示例代码中使用的流控制器,但是为 BlocA 创建了一个新事件,当用户在屏幕之间切换并将适当的状态数据下沉到流中时,它会被触发。 该事件带有一个索引字段来指示路由到的屏幕。 事件的索引对应于 navBar 索引。
事件处理实现如下所示:
FutureOr<void> _onScreenChanged(
ScreenChanged event,
Emitter<BlocAState> emit,
) async {
switch (event.index) {
case 0:
_aStream.sink.add(state.fieldX);
break;
case 1:
_bStream.sink.add(state.fieldY);
break;
default:
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.