Flutter从其他Bloc收听Bloc状态

时间:2019-12-02 10:39:23

标签: flutter flutter-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时返回:

stateAuth = {AuthenticationAuthenticated} AuthenticationAuthenticated
   props = {_ImmutableList} size = 0

但是 stateAuth是AuthenticationAuthenticated 总是返回false。

有什么方法可以从其他Bloc类中监听blocState吗?

3 个答案:

答案 0 :(得分:9)

要回答Sampir的问题,是的,您是对的,但有时您可能想以其他方式来做。 团体是为其他人管理事件的东西。如果您正在使用ui事件,您的集团将为您的ui管理它们,但是如果您还使用其他类型的事件(例如,位置事件或其他流事件),则可以拥有一个用于管理ui事件和其他集团的集团管理其他类型的事件(即蓝牙连接)。因此,第一个集团必须收听第二个集团(即因为正在等待建立蓝牙连接)。考虑一个使用大量传感器的应用程序,每个传感器都有其数据流,您将拥有一系列必须合作的集团。 您可以使用多提供者和多侦听器来做到这一点,但是您的链可能会很长,并且编写侦听器案例可能很困难,或者您可能希望将其隐藏在用户界面中,或者想在其他部分重用它应用程序,因此您可能想在自己的集团内部建立链。

您几乎可以在任何地方将侦听器添加到集团中。使用StreamSubscription,您可以为每种流添加侦听器,甚至可以将侦听器添加到另一块中。该集团必须具有公开他的信息流的方法,以便您可以听他讲话。

一些代码(我使用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
}

答案 1 :(得分:8)

实际上,他们在examples中的一个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

答案 2 :(得分:0)

为什么要在Bloc中加入Bloc? 尝试在页面中同时使用两个块,我认为对于您来说,它应该很好用。 同样很容易实现,Bloc有MultiBlocProvider