简体   繁体   English

Flutter 从其他集团听集团 state

[英]Flutter listen Bloc state from Other Bloc

Hello I'm trying to listen state of bloc form other bloc.您好,我正在尝试收听 state of bloc form other bloc。 I'm using this package https://pub.dev/packages/bloc我正在使用这个 package https://pub.dev/packages/bloc

From my UserBloc I want listen AuthBloc and when It has the state AuthenticationAuthenticated the UserBloc should fire an event.从我的UserBloc我想听AuthBloc ,当它有 state 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();
  }

For now I have this problem: When in debug I'm trying to print stateAuth it return:现在我有这个问题:在调试时我试图打印 stateAuth 它返回:

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

But stateAuth is AuthenticationAuthenticated return always false.但是stateAuth 是 AuthenticationAuthenticated返回总是 false。

Is there any way for listen blocState From Other Bloc class?有什么办法可以从其他 Bloc class 监听 blocState 吗?

To answer Sampir's question, yes, you're right, but sometimes you may want to do it in another way.要回答 Sampir 的问题,是的,您是对的,但有时您可能想以另一种方式来回答。 A bloc is something that manages an event for someone else.集团是为其他人管理事件的东西。 If you are working with ui events, your bloc manages them for your ui, but if you are working also with other kind of events (ie position events, or other streams events) you can have a bloc that manages your ui events and antoher bloc that manages the other kind of events (ie a bluetooth connection).如果您正在使用 ui 事件,您的 bloc 会为您的 ui 管理它们,但如果您还使用其他类型的事件(即位置事件或其他流事件),您可以有一个 bloc 来管理您的 ui 事件和另一个 bloc管理其他类型的事件(即蓝牙连接)。 So the first bloc must listen to the second one (ie because is waiting for establishing bluetooth connection).所以第一个块必须听第二个(即因为正在等待建立蓝牙连接)。 Think about an app that uses a lot of sensors, each one with its stream of data, and you'll have a chain of blocs that have to cooperate.考虑一个使用大量传感器的应用程序,每个传感器都有其数据流,您将拥有一系列必须合作的集团。 You can do it with multi-provider and multi-listener but your chain could be very long and writing your listener cases can be hard, or you may want to hide it from your ui, or you want to reuse it in another part of your app, so you may want to build your chain inside your blocs.您可以使用多提供者和多侦听器来做到这一点,但是您的链可能很长,并且编写您的侦听器案例可能很困难,或者您可能希望将其隐藏在您的 ui 中,或者您想在您的另一部分重用它应用程序,因此您可能希望在您的集团内建立您的链。

You can add a listener to a bloc almost everywhere.您几乎可以在任何地方将侦听器添加到 bloc。 Using StreamSubscription, you can add a listener to every kind of streams, even the one in another bloc.使用 StreamSubscription,您可以为每种类型的流添加侦听器,甚至是另一个块中的流。 The bloc must have a method to expose his stream, so you can listen to him.该集团必须有一种方法来公开他的流,这样你就可以听他的了。

Some code (I use flutter_bloc - flutter_bloc has multi-providers, but it's just for example):一些代码(我使用 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
}

Actually in one of the examples of the bloc library they listen to a Bloc (TodosBloc) from another Bloc (FilteredTodosBloc).实际上,在bloc 库的一个示例中,他们从另一个 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));
      }
    });
  }
...

You can check this example's explanation here .您可以在此处查看此示例的说明。

A recent update in the bloc source code requires a small change to the solution. bloc 源代码的最新更新需要对解决方案进行小幅更改。

You now have to listen to a bloc/cubit's stream attribute, please see below example.你现在必须听一个 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));
      }
    });
  }
...

For those still looking (especially the best practice kinda people), You might not want your bloc to depend on another bloc with the direct bloc-to-bloc dependency, instead you might want to connect your bloc through the presentation layer.对于那些仍在寻找的人(尤其是最佳实践的人),您可能不希望您的 bloc 依赖于具有直接 bloc-to-bloc 依赖关系的另一个 bloc,而是您可能希望通过表示层连接您的 bloc。 for example:例如:

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());
        },
      ),
    );
  }
}

Pls, check the official documentation for more info.请查看官方文档以获取更多信息。

For people who don't want to disturb the bloc,对于不想扰乱集团的人,

we can use this library Event Bus .我们可以使用这个库Event Bus It is based on stream. we can fire and listen events from anywhere between the screens.它基于 stream。我们可以从屏幕之间的任何位置触发和监听事件。

// declare this globally

EventBus eventBus = EventBus();


// create event
class UserLoggedInEvent {
  User user;

  UserLoggedInEvent(this.user);
}


// listen event
eventBus.on<UserLoggedInEvent>().listen((event) {
  // All events are of type UserLoggedInEvent (or subtypes of it).
  print(event.user);
});


// fire event
User myUser = User('Mickey');
eventBus.fire(UserLoggedInEvent(myUser));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM