Некоторые события, добавленные в MultiBlocProvider, не отправляются Flutter - PullRequest
0 голосов
/ 19 апреля 2020

Я добавил новый блок blo c SyncBloc в пакет MultiBlocProvider (flutter_bloc), который создает все блоки, необходимые для MapScreen, а для некоторых также добавляет события, необходимые для представления данных на экране. сам. Проблема в том, что, хотя события местоположения (для LocationBloc) добавляются правильно из самого MultiBlocProvider, события syn c (для SyncBloc) - нет. Если я вместо этого добавлю их из MultiBlocListener MapScreen как

BlocProvider.of<SyncBloc>(context).add(SyncLanguages());

, они будут работать, как и ожидалось, поэтому похоже, что SyncBloc был предоставлен правильно. SyncBloc или укажете мне правильное направление? Как всегда, большое спасибо за ваше время и помощь.

Это MultiBlocProvider в main():

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: [
        const AppLocalizationsDelegate(),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: [
        const Locale('en', ''),
        const Locale('it', ''),
        const Locale('es', ''),
      ],
      localeResolutionCallback:
          (Locale locale, Iterable<Locale> supportedLocales) {
        for (Locale supportedLocale in supportedLocales) {
          if (supportedLocale.languageCode == locale.languageCode ||
              supportedLocale.countryCode == locale.countryCode) {
            return supportedLocale;
          }
        }
        return supportedLocales.first;
      },
      debugShowCheckedModeBanner: false,
      home: BlocBuilder<AuthenticationBloc, AuthenticationState>(
        builder: (context, state) {
          if (state is Unauthenticated) {
            return LoginScreen(userRepository: _userRepository);
          }
          if (state is Authenticated) {
            return MultiBlocProvider(
              providers: [
                BlocProvider<TrackingBloc>(
                  create: (context) => TrackingBloc(),
                ),
                BlocProvider<DirectionsBloc>(
                  create: (context) => DirectionsBloc(),
                ),
                BlocProvider<GeoBloc>(
                  create: (context) => GeoBloc(),
                ),
                BlocProvider<RouteBloc>(
                  create: (context) => RouteBloc(),
                ),
                BlocProvider<SchedulerBloc>(
                  create: (context) => SchedulerBloc(),
                ),
                BlocProvider<CheckerBloc>(
                  create: (context) => CheckerBloc(),
                ),
                BlocProvider<LocationBloc>(
                    create: (context) => LocationBloc(
                          mapRepository: _mapRepository,
                        )
                          ..add(GetLocationStream())
                          ..add(GetLocation())
                          ..add(GetIsoLocationUser())),
                BlocProvider<SyncBloc>(
                    create: (context) =>
                        SyncBloc()..add(SyncLanguages())..add(SyncIcons())),
                BlocProvider<AlertBloc>(create: (context) {
                  return AlertBloc(
                    alertRepository: _alertRepository,
                  );
                }),
              ],
              child: MapScreen(
//                mapRepository: _mapRepository,
                user: state.user,
//              alertRepository: FirebaseAlertRepository(),
              ),
            );
          }
          return SplashScreen();
        },
      ),
      navigatorObservers: [
        FirebaseAnalyticsObserver(analytics: analytics),
      ],
    );

SyncEvent:

abstract class SyncEvent {
  const SyncEvent();

  @override
  List<Object> get props => [];
}

class SyncLanguages extends SyncEvent {}

class SyncIcons extends SyncEvent {}

и SyncBlo c:

class SyncBloc extends Bloc<SyncEvent, SyncState> {
  @override
  SyncState get initialState => InitialState();

  Stream<SyncState> mapEventToState(SyncEvent event) async* {
    if (event is SyncLanguages) {
      print('SyncLanguages received');
    }
    if (event is SyncIcons) {
      print('SyncIcons received');
    }
  }
}

1 Ответ

0 голосов
/ 20 апреля 2020

Проблема связана с тем, что метод создания BlocProvider по умолчанию ленив. Таким образом, пока метод .of не будет вызван, BlocProvider не будет создавать блок blo c. Чтобы заставить его создать blo c немедленно, просто установите для параметра lazy: значение false.

BlocProvider<LocationBloc>(
                    lazy: false,
                    create: (context) => LocationBloc(
                          mapRepository: _mapRepository,
                        )
                          ..add(GetLocationStream())
                          ..add(GetLocation())
                          ..add(GetIsoLocationUser())),
                BlocProvider<SyncBloc>(
                    lazy: false,
                    create: (context) => SyncBloc()
                      ..add(SyncLanguages())
                      ..add(SyncIcons())),

Это действительно работает, хотя события AuthenticationBlo c и LocationBlo c были отправлены даже без параметра lazy установить в ложь. Еще нужно проверить, почему это так, но я предполагаю, что эти два блока создаются соответственно BlocBuilder и BlocListener. Я отредактирую ответ, как только узнаю наверняка.

...