如何使 bloc 中的对象可用于 Flutter 中的所有其他 bloc

How to make an object from a bloc available for all other bloc in Flutter

我正在为我的 Flutter 项目使用 Bloc。我创建了三个集团。它们是 AuthenticationBloc、FirebaseDatabaseBloc 和 ChatMessagesBloc。当用户通过身份验证时,AuthenticationBloc 会发出一个名为已通过用户对象身份验证的状态。

我想让这个用户对象在 FirebaseDatabaseBloc 和 ChatMessagesBloc 中可用。这样做的干净方法是什么?

这可以通过 BLoC 到 BLoC 的通信来实现。最简单的方法是通过对方的构造函数传递您的 BLoC 引用并订阅 BLoC 更改:

@override
Widget build(BuildContext context) {
  final authenticationBloc = AuthenticationBloc();

  return MultiBlocProvider(
    providers: [
      BlocProvider<AuthenticationBloc>.value(value: authenticationBloc),
      BlocProvider<FirebaseDatabaseBloc>(
        create: (_) => FirebaseDatabaseBloc(
          authenticationBloc: authenticationBloc,
        ),
      ),
    ],
    child: ...,
  );
}

然后,在 FirebaseDatabaseBloc 中您可以订阅更改:

class FirebaseDatabaseBloc extends Bloc<FirebaseDatabaseEvent, FirebaseDatabaseBloc> {
  final AuthenticationBloc authenticationBloc;

  StreamSubscription<AuthenticationState> _authenticationStateStreamSubscription;

  FirebaseDatabaseBloc({
    @required this.authenticationBloc,
  }) : super(...) {
    _authenticationStateStreamSubscription = authenticationBloc.listen(_onAuthenticationBlocStateChange);
  }

  @override
  Future<void> close() async {
    _authenticationStateStreamSubscription.cancel();

    return super.close();
  }

  void _onAuthenticationBlocStateChange(AuthenticationState authState) {
    // Do whatever you want with the auth state
  }
}

更多信息,您可以观看此视频:https://www.youtube.com/watch?v=ricBLKHeubM

好吧,今年是 2022 年,发生了很多变化。 Bloc to Bloc to communication via the constructor 现在被认为是一种不好的做法。虽然没有人说它行不通,但请相信我,您最终会紧密耦合您的代码。

Generally, sibling dependencies between two entities in the same architectural layer should be avoided at all costs, as it creates tight-coupling which is hard to maintain. Since blocs reside in the business logic architectural layer, no bloc should know about any other bloc. documentation.

你应该试试这个:

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

希望对您有所帮助!