首页 > 解决方案 > 颤振集团。在 mapEventToState() 中产生的状态中,我无法获取要传递的值

问题描述

我刚刚开始使用 Flutter,我仍然不确定构建事件/状态/BLoc/Repositoy 类以正确使用此模式的逻辑。location当产生一个将值作为输入的状态时,我一直坚持将值从集团中返回给 UI。

从存储库开始,我有从以下位置getLocation()获取坐标的方法Geolocator locationManager

Future<LatLng> getLocation() async {
    try {
      locationManager
          .getCurrentPosition(
              desiredAccuracy: LocationAccuracy.bestForNavigation)
          .timeout(Duration(seconds: 5));
    } catch (error) {
      print(
          'getLocation(): error getting current location: ${error.toString()}');
    }
  }

然后我有GetLocation活动

class GetLocation extends MapEvent {
      final LatLng location;
      const GetLocation(this.location);
      @override
      List<Object> get props => [location];

      @override
      String toString() => 'GetLocation { current location: $location}';
    }

在屏幕加载时发送到 bloc 以显示地图,并通过按钮将地图置于用户位置的中心。

BlocProvider<MapBloc>(create: (context) {
          return MapBloc(mapRepository: MapRepository())..add(GetLocation());
        }),

然后MapLoaded是持有该位置的状态:

class MapLoaded extends MapState {
  final LatLng location;

  const MapLoaded(this.location);

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

  @override
  String toString() => 'MapLoaded {location: $location}';
}

这是建立在该状态上的小部件:

BlocBuilder<MapBloc, MapState>(
                  bloc: MapBloc(mapRepository: _mapRepository),
                  builder: (BuildContext context, MapState state) {
                    final LatLng location = (state as MapLoaded).location;
                    return Container

最后是我找不到将位置作为输入传递MapState()给事件以响应事件的区域:

class MapBloc extends Bloc<MapEvent, MapState> {
  final MapRepository _mapRepository;
  StreamSubscription _locationStreamSubscription;

  MapBloc(
      {@required MapRepository mapRepository,
      @required StreamSubscription streamSubscription})
      : assert(mapRepository != null || streamSubscription != null),
        _mapRepository = mapRepository,
        _locationStreamSubscription = streamSubscription;

  MapState get initialState => MapLoading();

  @override
  Stream<MapState> mapEventToState(MapEvent event) async* {
    if (event is GetLocation) {
      yield* _mapGetLocationToState();
    }

    if (event is GetTracking) {
      yield* _mapGetTrackingToState();
    }

    if (event is LocationUpdated) {
    // CANT GET LOCATION TO PASS IN MapLoaded()
      yield MapLoaded();
    }
  }

  Stream<MapState> _mapGetLocationToState() async* {
    _mapRepository.getLocation();


    (location) => add(LocationUpdated(location));
    // CANT GET LOCATION TO PASS IN MapLoaded()
    yield MapLoaded(l);

  }

  Stream<MapState> _mapGetTrackingToState() async* {
    _mapRepository.setTracking();
  }
}

在里面Stream<MapState> _mapGetLocationToState()我试图发送一个add(LocationUpdated(location))事件并 Stream<MapState> mapEventToState让步MapLoaded(),但我找不到任何方法来传递该位置。我也尝试直接在其中产生它,Stream<MapState> _mapGetLocationToState()但结果相同。

你能看出我做错了什么吗?切换到反应式编程并不是那么容易,但我已经到了。这是我第一次尝试这种模式,我还没有完全理解所有的概念,所以我肯定认为有些类是错误的。非常感谢您的时间和帮助,并对这个冗长的问题感到抱歉。干杯。

标签: flutterbloc

解决方案


_mapGetLocationToState()没有事件作为参数。

@override
  Stream<MapState> mapEventToState(MapEvent event) async* {
    if (event is GetLocation) {
      yield* _mapGetLocationToState(event);
    }

    if (event is GetTracking) {
      yield* _mapGetTrackingToState();
    }

    if (event is LocationUpdated) {
    // CANT GET LOCATION TO PASS IN MapLoaded()
      yield MapLoaded();
    }
  }

  Stream<MapState> _mapGetLocationToState(GetLocation event) async* {
    // now you have event.location
    _mapRepository.getLocation();


    (location) => add(LocationUpdated(location));
    // CANT GET LOCATION TO PASS IN MapLoaded(event.location)
    yield MapLoaded(event.location);

  }

  Stream<MapState> _mapGetTrackingToState() async* {
    _mapRepository.setTracking();
  }
}

编辑: BlocProvider任务是创建你想要的 Bloc 类的实例。在这种情况下MapBloc。如您所见,您的MapBloc类有 2 个依赖项,MapRepository并且StreamSubscription. 所以当BlocProvider想要创建它的实例时,你需要通过构造函数来提供它需要的那些东西。与 相同GetLocation,您需要提供 LatLng 因为它取决于它。

BlocProvider<MapBloc>(create: (context) {
  return MapBloc(
           mapRepository: MapRepository(),
           streamSubscription: ...?
         )..add(GetLocation(...?));
}),

推荐阅读