是否有可能监听许多 BloC 的状态?
Is it possible listen state of many BloC?
在询问了 Flutter 中的状态管理之后() without having any answer I decided to use BLoC Package 这在我看来是最清晰和最容易使用的。
现在在我的 flutter 应用程序中,我有 BlocA、BlocB 和 BlocC,我想从 BlocC 监听 BlocA 和 BlocB 的状态变化。
所有区块上具有相同 states/event 的示例(更新、更新/更新):
class BlocC extends Bloc<CEvent, CState> {
final BlocA a;
final BlocB b;
StreamSubscription aSubscription;
BlocC({@required this.a, @required this.b}) {
aSubscription = a.state.listen((state) {
if (state is AUpdated) {
dispatch(UpdateC());
}
});
}
@override
CState get initialState => CUpdating();
@override
Stream<CState> mapEventToState(CEvent event) async* {
if (event is UpdateC && b.currentState is BUpdated) {
yield* CUpdated();
}
}
...
在这种情况下,当从 BlocA 状态分派事件时,BlocB 的状态有时不会在 _mapEventToState 方法中更新,并且我的侦听器无法工作。
所以我认为有一种方法可以将一个 bloc 订阅到许多流中,以获得所有流的正确状态转换。
你能帮帮我吗?
这是预期的行为,因为您仅在 BlocA
的状态为 AUpdated
时才调度 UpdateC()
,而当 BlocB
的状态也为 BUpdated
.
而且即使你的调度事件改变了 BlocA
和 BlocB
的状态同时更新,这是异步的,所以你不能保证 event is UpdateC && b.currentState is BUpdated
可以永远是真的。所以你失去了一些 UpdateC
事件。
对于您的情况,您可以使用 rxdart 的 combineLastest2。并且仅当 BlocA
和 BlocB
同时具有 Updated
状态时才调度 UpdateC()
。
import 'package:rxdart/rxdart.dart';
class BlocC extends Bloc<CEvent, CState> {
final BlocA a;
final BlocB b;
StreamSubscription<bool> _canUpdateCSubscription;
BlocC({@required this.a, @required this.b}) {
_canUpdateCSubscription = Observable.combineLatest2(
a.state,
b.state,
(aState, bState) => aState is AUpdated && bState is BUpdated,
).listen(
(canUpdateC) {
if (canUpdateC) dispatch(UpdateC());
},
);
}
@override
void dispose() {
_canUpdateCSubscription?.cancel();
_canUpdateCSubscription = null;
super.dispose();
}
@override
CState get initialState => CUpdating();
@override
Stream<CState> mapEventToState(CEvent event) async* {
if (event is UpdateC) {
yield* CUpdated();
}
}
...
在询问了 Flutter 中的状态管理之后(
所有区块上具有相同 states/event 的示例(更新、更新/更新):
class BlocC extends Bloc<CEvent, CState> {
final BlocA a;
final BlocB b;
StreamSubscription aSubscription;
BlocC({@required this.a, @required this.b}) {
aSubscription = a.state.listen((state) {
if (state is AUpdated) {
dispatch(UpdateC());
}
});
}
@override
CState get initialState => CUpdating();
@override
Stream<CState> mapEventToState(CEvent event) async* {
if (event is UpdateC && b.currentState is BUpdated) {
yield* CUpdated();
}
}
...
在这种情况下,当从 BlocA 状态分派事件时,BlocB 的状态有时不会在 _mapEventToState 方法中更新,并且我的侦听器无法工作。 所以我认为有一种方法可以将一个 bloc 订阅到许多流中,以获得所有流的正确状态转换。
你能帮帮我吗?
这是预期的行为,因为您仅在 BlocA
的状态为 AUpdated
时才调度 UpdateC()
,而当 BlocB
的状态也为 BUpdated
.
而且即使你的调度事件改变了 BlocA
和 BlocB
的状态同时更新,这是异步的,所以你不能保证 event is UpdateC && b.currentState is BUpdated
可以永远是真的。所以你失去了一些 UpdateC
事件。
对于您的情况,您可以使用 rxdart 的 combineLastest2。并且仅当 BlocA
和 BlocB
同时具有 Updated
状态时才调度 UpdateC()
。
import 'package:rxdart/rxdart.dart';
class BlocC extends Bloc<CEvent, CState> {
final BlocA a;
final BlocB b;
StreamSubscription<bool> _canUpdateCSubscription;
BlocC({@required this.a, @required this.b}) {
_canUpdateCSubscription = Observable.combineLatest2(
a.state,
b.state,
(aState, bState) => aState is AUpdated && bState is BUpdated,
).listen(
(canUpdateC) {
if (canUpdateC) dispatch(UpdateC());
},
);
}
@override
void dispose() {
_canUpdateCSubscription?.cancel();
_canUpdateCSubscription = null;
super.dispose();
}
@override
CState get initialState => CUpdating();
@override
Stream<CState> mapEventToState(CEvent event) async* {
if (event is UpdateC) {
yield* CUpdated();
}
}
...