Flutter 监听来自 Other Bloc 的 Bloc 状态
Flutter listen Bloc state from Other Bloc
你好,我正在尝试从其他集团中收听集团的状态。
我正在使用这个包 https://pub.dev/packages/bloc
来自我的 UserBloc 我想听 AuthBloc 并且当它具有状态 AuthenticationAuthenticated 时UserBloc 应该触发一个事件。
final UserRepository userRepository;
final authBloc;
StreamSubscription authSub;
UserBloc({ @required this.userRepository, @required this.authBloc}) {
authSub = authBloc.listen((stateAuth) {
//here is my problem because stateAuth, even is AuthenticationAuthenticated it return always false.
if (stateAuth is AuthenticationAuthenticated) {
this.add(GetUser()) ;
}
});
}
@override
Future<void> close() async {
authSub?.cancel();
super.close();
}
现在我有这个问题:
在调试时,我试图打印 stateAuth it return:
stateAuth = {AuthenticationAuthenticated} AuthenticationAuthenticated
props = {_ImmutableList} size = 0
但是 stateAuth 是 AuthenticationAuthenticated return 始终为假。
有什么方法可以从其他 Bloc 监听 blocState class?
要回答 Sampir 的问题,是的,你是对的,但有时你可能想以另一种方式来做。
集团是为其他人管理事件的东西。如果您正在处理 ui 事件,您的 bloc 会为您的 ui 管理它们,但如果您还处理其他类型的事件(即位置事件或其他流事件),您可以拥有一个 bloc管理您的 ui 事件和管理其他类型事件(即蓝牙连接)的 antoher 集团。所以第一个集团必须听第二个集团(即因为正在等待建立蓝牙连接)。考虑一个使用大量传感器的应用程序,每个传感器都有其数据流,并且您将拥有一系列必须合作的集团。
您可以使用多提供商和多侦听器来实现,但是您的链可能很长并且编写侦听器案例可能很困难,或者您可能希望将其隐藏在 ui 中,或者您希望在您应用程序的另一部分,因此您可能希望在您的区块中构建您的链。
您几乎可以在任何地方向集团添加侦听器。使用 StreamSubscription,您可以为各种流添加侦听器,甚至是另一个集团中的流。 bloc肯定有办法公开他的流,这样你就可以听他的了。
一些代码(我使用flutter_bloc - flutter_bloc有多个供应商,但它只是为了举例):
class BlocA extends Bloc<EventA, StateA> {
final BlocB blocB;
StreamSubscription subscription;
BlocA({this.blocB}) {
if (blocB == null) return;
subscription = blocB.listen((stateB) {
//here logic based on different children of StateB
});
}
//...
}
class BlocB extends Bloc<EventB, StateB> {
//here BlocB logic and activities
}
实际上,在其中一个 examples of the bloc library 中,他们从另一个 Bloc (FilteredTodosBloc) 中收听一个 Bloc (TodosBloc)。
class FilteredTodosBloc extends Bloc<FilteredTodosEvent, FilteredTodosState> {
final TodosBloc todosBloc;
StreamSubscription todosSubscription;
FilteredTodosBloc({@required this.todosBloc}) {
todosSubscription = todosBloc.listen((state) {
if (state is TodosLoadSuccess) {
add(TodosUpdated((todosBloc.state as TodosLoadSuccess).todos));
}
});
}
...
你可以查看这个例子的解释here。
bloc 源代码的最新更新需要对解决方案进行小的更改。
您现在必须收听 bloc/cubit 的流属性,请参见下面的示例。
class FilteredTodosBloc extends Bloc<FilteredTodosEvent, FilteredTodosState> {
final TodosBloc todosBloc;
StreamSubscription todosSubscription;
FilteredTodosBloc({@required this.todosBloc}) {
todosSubscription = todosBloc.stream.listen((state) {
// ^^^^^
if (state is TodosLoadSuccess) {
add(TodosUpdated((todosBloc.state as TodosLoadSuccess).todos));
}
});
}
...
对于那些仍在寻找的人(尤其是最佳实践者),您可能不希望您的集团依赖于另一个具有直接 bloc-to-bloc 依赖性的集团,相反您可能希望通过演示文稿连接您的集团层。例如:
class MyWidget extends StatelessWidget {
const MyWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocListener<WeatherCubit, WeatherState>(
listener: (context, state) {
// When the first bloc's state changes, this will be called.
//
// Now we can add an event to the second bloc without it having
// to know about the first bloc.
BlocProvider.of<SecondBloc>(context).add(SecondBlocEvent());
},
child: TextButton(
child: const Text('Hello'),
onPressed: () {
BlocProvider.of<FirstBloc>(context).add(FirstBlocEvent());
},
),
);
}
}
请查看官方documentation了解更多信息。
你好,我正在尝试从其他集团中收听集团的状态。 我正在使用这个包 https://pub.dev/packages/bloc
来自我的 UserBloc 我想听 AuthBloc 并且当它具有状态 AuthenticationAuthenticated 时UserBloc 应该触发一个事件。
final UserRepository userRepository;
final authBloc;
StreamSubscription authSub;
UserBloc({ @required this.userRepository, @required this.authBloc}) {
authSub = authBloc.listen((stateAuth) {
//here is my problem because stateAuth, even is AuthenticationAuthenticated it return always false.
if (stateAuth is AuthenticationAuthenticated) {
this.add(GetUser()) ;
}
});
}
@override
Future<void> close() async {
authSub?.cancel();
super.close();
}
现在我有这个问题: 在调试时,我试图打印 stateAuth it return:
stateAuth = {AuthenticationAuthenticated} AuthenticationAuthenticated
props = {_ImmutableList} size = 0
但是 stateAuth 是 AuthenticationAuthenticated return 始终为假。
有什么方法可以从其他 Bloc 监听 blocState class?
要回答 Sampir 的问题,是的,你是对的,但有时你可能想以另一种方式来做。 集团是为其他人管理事件的东西。如果您正在处理 ui 事件,您的 bloc 会为您的 ui 管理它们,但如果您还处理其他类型的事件(即位置事件或其他流事件),您可以拥有一个 bloc管理您的 ui 事件和管理其他类型事件(即蓝牙连接)的 antoher 集团。所以第一个集团必须听第二个集团(即因为正在等待建立蓝牙连接)。考虑一个使用大量传感器的应用程序,每个传感器都有其数据流,并且您将拥有一系列必须合作的集团。 您可以使用多提供商和多侦听器来实现,但是您的链可能很长并且编写侦听器案例可能很困难,或者您可能希望将其隐藏在 ui 中,或者您希望在您应用程序的另一部分,因此您可能希望在您的区块中构建您的链。
您几乎可以在任何地方向集团添加侦听器。使用 StreamSubscription,您可以为各种流添加侦听器,甚至是另一个集团中的流。 bloc肯定有办法公开他的流,这样你就可以听他的了。
一些代码(我使用flutter_bloc - flutter_bloc有多个供应商,但它只是为了举例):
class BlocA extends Bloc<EventA, StateA> {
final BlocB blocB;
StreamSubscription subscription;
BlocA({this.blocB}) {
if (blocB == null) return;
subscription = blocB.listen((stateB) {
//here logic based on different children of StateB
});
}
//...
}
class BlocB extends Bloc<EventB, StateB> {
//here BlocB logic and activities
}
实际上,在其中一个 examples of the bloc library 中,他们从另一个 Bloc (FilteredTodosBloc) 中收听一个 Bloc (TodosBloc)。
class FilteredTodosBloc extends Bloc<FilteredTodosEvent, FilteredTodosState> {
final TodosBloc todosBloc;
StreamSubscription todosSubscription;
FilteredTodosBloc({@required this.todosBloc}) {
todosSubscription = todosBloc.listen((state) {
if (state is TodosLoadSuccess) {
add(TodosUpdated((todosBloc.state as TodosLoadSuccess).todos));
}
});
}
...
你可以查看这个例子的解释here。
bloc 源代码的最新更新需要对解决方案进行小的更改。
您现在必须收听 bloc/cubit 的流属性,请参见下面的示例。
class FilteredTodosBloc extends Bloc<FilteredTodosEvent, FilteredTodosState> {
final TodosBloc todosBloc;
StreamSubscription todosSubscription;
FilteredTodosBloc({@required this.todosBloc}) {
todosSubscription = todosBloc.stream.listen((state) {
// ^^^^^
if (state is TodosLoadSuccess) {
add(TodosUpdated((todosBloc.state as TodosLoadSuccess).todos));
}
});
}
...
对于那些仍在寻找的人(尤其是最佳实践者),您可能不希望您的集团依赖于另一个具有直接 bloc-to-bloc 依赖性的集团,相反您可能希望通过演示文稿连接您的集团层。例如:
class MyWidget extends StatelessWidget {
const MyWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocListener<WeatherCubit, WeatherState>(
listener: (context, state) {
// When the first bloc's state changes, this will be called.
//
// Now we can add an event to the second bloc without it having
// to know about the first bloc.
BlocProvider.of<SecondBloc>(context).add(SecondBlocEvent());
},
child: TextButton(
child: const Text('Hello'),
onPressed: () {
BlocProvider.of<FirstBloc>(context).add(FirstBlocEvent());
},
),
);
}
}
请查看官方documentation了解更多信息。