简体   繁体   English

BlocProvider.of() 使用不包含 TrackingBloc 类型的 Bloc 的上下文调用

[英]BlocProvider.of() called with a context that does not contain a Bloc of type TrackingBloc

I'm trying to provide a TrackingBloc to MapScreen but when sending an event from onPressed I get the error BlocProvider.of() called with a context that does not contain a Bloc of type TrackingBloc.我正在尝试向MapScreen提供TrackingBloc ,但是当从onPressed发送事件时,我收到错误BlocProvider.of() called with a context that does not contain a Bloc of type TrackingBloc. MapScreen also uses a MapBloc provided from main() , but for TrackingBloc I want to make it local, not to clutter MultiBlocProvider in main() . MapScreen还使用从main()提供的MapBloc ,但对于TrackingBloc我想让它本地化,而不是在main() MultiBlocProvider I tried:我试过:

  1. To use the bloc: parameter in the BlocListener<TrackingBloc, TrackingState> , as I've been told that it just provides the bloc as a BlocProvider would( https://github.com/felangel/bloc/issues/930#issuecomment-593790702 ) but it didn't work.要在BlocListener<TrackingBloc, TrackingState>使用bloc:参数,因为我被告知它只是像BlocProvider那样提供 bloc( https://github.com/felangel/bloc/issues/930#issuecomment- 593790702 )但它没有用。
  2. Then I tried making MultiBlocLister a child of a MultiBlocProvider and set TrackingBloc there, but still get the message.然后我尝试使MultiBlocLister成为MultiBlocLister的子MultiBlocProvider并在那里设置TrackingBloc ,但仍然收到消息。
  3. Set TrackingBloc in the MultiBlocProvider in `main() and worked as expected.在 `main() 的MultiBlocProvider中设置TrackingBloc MultiBlocProvider预期工作。

Why 1 and 2 don't provide TrackingBloc to the tree?为什么 1 和 2 不向树提供TrackingBloc Many thanks for your help.非常感谢您的帮助。

MapScreen:地图屏幕:

class MapScreen extends StatefulWidget {
  final String name;
  final MapRepository _mapRepository;

  MapScreen(
      {Key key, @required this.name, @required MapRepository mapRepository})
      : assert(mapRepository != null),
        _mapRepository = mapRepository,
        super(key: key);

  @override
  _MapScreenState createState() => _MapScreenState();
}

class _MapScreenState extends State<MapScreen> {
  List<Marker> alerts;
  LatLng userLocation;

  MapController _mapController = MapController();

  @override
  Widget build(BuildContext context) {
    return MultiBlocProvider(
      providers: [
        BlocProvider<TrackingBloc>(create: (context) {
          return TrackingBloc();
        }),
      ],
      child: MultiBlocListener(
        listeners: [
          BlocListener<MapBloc, MapState>(
              listener: (BuildContext context, MapState state) {
            if (state is LocationStream) {
              setState(() {
                userLocation = (state).location;
//              print(
//                  ' @@@@ MapBloc actual user location from stream  is : $userLocation');
              });
            }
            if (state is MapCenter) {
              userLocation = (state).location;
//            print(' @@@@ MapBloc initial center location is : $userLocation');
              _mapController.move(userLocation, 16);
            }
          }),
          BlocListener<TrackingBloc, TrackingState>(
//              bloc: TrackingBloc(),
              listener: (BuildContext context, TrackingState state) {
            if (state is TrackedRoute) {
              List<Position> route = (state).trackedRoute;
              print(route);
            }
          }),
        ],
        child: Scaffold(

main():主要的():

  runApp(
    MultiBlocProvider(
      providers: [
        BlocProvider<AuthenticationBloc>(
          create: (context) {
            return AuthenticationBloc(
              userRepository: UserRepository(),
            )..add(AppStarted());
          },
        ),
        BlocProvider<MapBloc>(create: (context) {
          return MapBloc(
            mapRepository: mapRepository,
          )
            ..add(GetLocationStream())
            ..add(GetLocation());
        }),
        BlocProvider<TrackingBloc>(create: (context) {
          return TrackingBloc();
        }),
//        BlocProvider<AlertBloc>(create: (context) {
//          return AlertBloc(
//            alertRepository: alertRepository,
//          )..add(LoadAlerts());
//        }),
      ],
      child:

Right of the bat, I can see two things are wrong with your code.蝙蝠的右边,我可以看到您的代码有两处错误。

First: You provide multiple TrackingBloc, in main and MapScreen.第一:您在 main 和 MapScreen 中提供多个 TrackingBloc。

Second: You are accessing TrackingBloc via BlocListener within the same context where you provide it (the second BlocProvider(create: (context) {return TrackingBloc();}) ).第二:您在提供它的同一上下文中通过 BlocListener 访问 TrackingBloc(第二个BlocProvider(create: (context) {return TrackingBloc();}) )。 My guess is this is what causing the error.我的猜测是这就是导致错误的原因。

BlocProvider.of() called with a context that does not contain a Bloc of type TrackingBloc BlocProvider.of() 使用不包含 TrackingBloc 类型的 Bloc 的上下文调用

I think by simply removing BlocProvider in the MapScreen will do the job.我认为只需在 MapScreen 中删除 BlocProvider 就可以完成这项工作。

I was providing TrackingBloc from the wrong place in the widget tree.我从小部件树中错误的位置提供了TrackingBloc I can provide the bloc globally which I don't need, so to provide it locally as I want, I have to provide it from Blocbuilder in main() which is returning MapScreen .我可以在全局范围内提供我不需要的 bloc,因此要根据需要在本地提供它,我必须从返回MapScreen main() Blocbuilder提供它。

Changing main() from:main()更改为:

    return MaterialApp(
      home: BlocBuilder<AuthenticationBloc, AuthenticationState>(
        builder: (context, state) {
          if (state is Unauthenticated) {
            return LoginScreen(userRepository: _userRepository);
          }
          if (state is Authenticated) {
//            BlocProvider.of<MapBloc>(context).add(GetLocationStream());
//            BlocProvider.of<AlertBloc>(context).add(LoadAlerts());
            return MapScreen(
              mapRepository: _mapRepository,
              name: state.displayName,
//              alertRepository: FirebaseAlertRepository(),
            );
          }
          if (state is Unauthenticated) {
            return LoginScreen(userRepository: _userRepository);
          }
          return SplashScreen();
        },
      ),
    );

to:到:

return MaterialApp(
      home: BlocBuilder<AuthenticationBloc, AuthenticationState>(
        builder: (context, state) {
          if (state is Unauthenticated) {
            return LoginScreen(userRepository: _userRepository);
          }
          if (state is Authenticated) {
//            BlocProvider.of<MapBloc>(context).add(GetLocationStream());
//            BlocProvider.of<AlertBloc>(context).add(LoadAlerts());
            return MultiBlocProvider(
              providers: [
                BlocProvider<TrackingBloc>(create: (context) {
                  return TrackingBloc();
                }),
              ],
              child: MapScreen(
                mapRepository: _mapRepository,
                name: state.displayName,
//              alertRepository: FirebaseAlertRepository(),
              ),
            );
            return MapScreen(
              mapRepository: _mapRepository,
              name: state.displayName,
//              alertRepository: FirebaseAlertRepository(),
            );
          }
          if (state is Unauthenticated) {
            return LoginScreen(userRepository: _userRepository);
          }
          return SplashScreen();
        },
      ),
    );

makes it work as I intended.使它按我的意图工作。 Then in MapScreen I just use different BlocListener to listen to blocs being global as MapBloc or local as TrackingBloc :然后在MapScreen我只使用不同的BlocListener来收听全局作为MapBloc或本地作为TrackingBloc

class _MapScreenState extends State<MapScreen> {
  List<Marker> alerts;
  LatLng userLocation;

  MapController _mapController = MapController();

  @override
  Widget build(BuildContext context) {
    return MultiBlocListener(
      listeners: [
        BlocListener<MapBloc, MapState>(
            listener: (BuildContext context, MapState state) {
          if (state is LocationStream) {
            setState(() {
              userLocation = (state).location;
//              print(
//                  ' @@@@ MapBloc actual user location from stream  is : $userLocation');
            });
          }
          if (state is MapCenter) {
            userLocation = (state).location;
//            print(' @@@@ MapBloc initial center location is : $userLocation');
            _mapController.move(userLocation, 16);
          }
        }),
        BlocListener<TrackingBloc, TrackingState>(
//              bloc: TrackingBloc(),
            listener: (BuildContext context, TrackingState state) {
//      userLocation = (state as LocationStream).location;
          if (state is TrackedRoute) {
            List<Position> route = (state).trackedRoute;
            print(route);
//            initialLocation = (state).location.then((value) {
//              print('@@@@@@ value is : $value');
////              _mapController.move(value, 16.0);
//              return value;
//            }
//            );
          }
        }),
      ],
      child: Scaffold(

Hope this will help others just starting out with flutter_bloc that might not find documentation usage explanation of its widgets clearly enough.希望这会帮助其他刚开始使用flutter_bloc ,他们可能无法清楚地找到其小部件的文档使用说明。 Still have to fully understand BlocProvider 's and BlocListener 's bloc: property dough.. Cheers.仍然需要完全理解BlocProviderBlocListenerbloc: property 面团..干杯。

暂无
暂无

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

相关问题 Flutter 使用不包含 Bloc 类型的上下文调用的 BLoC BlocProvider.of() - Flutter BLoC BlocProvider.of() called with a context that does not contain a Bloc of type 使用不包含 FicheMvtBloc 类型的 Bloc 的上下文调用 BlocProvider.of() - BlocProvider.of() called with a context that does not contain a Bloc of type FicheMvtBloc BlocProvider.of() 使用不包含 OfflineBloc 类型的 Bloc 的上下文调用 - BlocProvider.of() called with a context that does not contain a Bloc of type OfflineBloc BlocProvider.of() 调用的上下文不包含 WeatherBloc 类型的 Bloc/Cubit - BlocProvider.of() called with a context that does not contain a Bloc/Cubit of type WeatherBloc Flutter:使用不包含 Bloc 类型的上下文调用 blocprovider.of() - Flutter: blocprovider.of() called with a context that does not contain a Bloc of type 使用不包含 Bloc 类型的上下文调用 BlocProvider.of() - BlocProvider.of() called with a context that does not contain a Bloc of type BlocProvider.of() 使用不包含 CLASS 类型的 Bloc 的上下文调用 - BlocProvider.of() called with a context that does not contain a Bloc of type CLASS 使用不包含 Bloc 类型的上下文调用 Flutter BlocProvider.of() - Flutter BlocProvider.of() called with a context that does not contain a Bloc of type 使用不包含 TaharatBloc 类型的 Bloc 的上下文调用 BlocProvider.of() - BlocProvider.of() called with a context that does not contain a Bloc of type TaharatBloc BlocProvider.of() 调用的上下文不包含 MyBloc 类型的 Bloc/Cubit - BlocProvider.of() called with a context that does not contain a Bloc/Cubit of type MyBloc
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM