颤振集团。我无法获得要传递给 mapEventToState() 中产生的状态的值`

Flutter Bloc . I can't get hold of a value to pass in the state I yield in mapEventToState()`

我刚刚开始使用 Flutter,我仍然不确定构建 event/state/BLoc/Repositoy 类 的逻辑以便正确使用此模式。当产生一个具有该值作为输入的状态时,我一直坚持将 location 值从 bloc 返回到 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() 中生成它,但结果相同。

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

您的 _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 class 实例。在这种情况下 MapBloc。如您所见,您的 MapBloc class 有 2 个依赖项,MapRepositoryStreamSubscription。所以当 BlocProvider 想要创建它的实例时,你需要通过构造函数提供它需要的那些东西。与GetLocation一样,需要提供LatLng,因为它依赖于它。

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