Flutter 使用 BloC 模式从 API 结果中获取列表元素

Flutter get list elements from API result with BloC Pattern

我是 BloC 模式的新手。我正在向天气 API 发送请求,它 return 是一个 JSON 结果,如下所示。 As you can see the result is array of json object

我在回复中将其格式化为天气模型 class。

天气模型Class

class Weather {
  String date;
  String day;
  String icon;
  String description;
  String status;
  String degree;
  String min;
  String max;
  String night;
  String humidity;

  Weather({this.date, this.day, this.icon, this.description, this.status,
      this.degree, this.min, this.max, this.night, this.humidity});

  Weather.init(this.date, this.day, this.icon);

  factory Weather.fromJson(Map<String, dynamic> json){
    return Weather(
      date: json['date'] as String,
      day:  json['day'] as String,
      icon: json['icon'] as String,
      description: json['description'] as String,
      status: json['status'] as String,
      degree: json['degree'] as String,
      min: json['min'] as String,
      max: json['max'] as String,
      night: json['night'] as String,
      humidity: json['humidity'] as String,
    );
  }

回复Class

class WeatherResponse {
  bool success;
  String city;
  List<Weather> result;

  WeatherResponse({this.success, this.city, this.result});

  factory WeatherResponse.fromJson(Map<String, dynamic> json) {
    var weathersFromJson = json['result'] as List<dynamic>;
    List<Weather> weatherList = List<Weather>();
    weathersFromJson.forEach((element) {
      Weather weather = Weather.fromJson(element);
      weatherList.add(weather);
    });

    return WeatherResponse(
      success: json['success'] as bool,
      city:  json['city'] as String,
      result: weatherList
    );

  }
}

天气集团

enum WeatherEvent { getWeather, getDetails }

class WeatherBloc extends Bloc<WeatherEvent, Weather> {
  WeatherBloc(Weather initialState) : super(initialState);

  @override
  Stream<Weather> mapEventToState(WeatherEvent event) async*{
    switch (event) {
      case WeatherEvent.getWeather:
        WeatherRequest().fetchWeathers().then((weatherResponse) =>
          weatherResponse.result.forEach((element) {
            return element;
          })
        );
        break;

      case WeatherEvent.getDetails:
        break;
    }
  }
}

我想使用 yield 而不是 return 元素,当数据到来时,我想将此数据天气列表结果元素发送到 UI。

UI 区块生成器

 BlocBuilder<WeatherBloc, Weather>(
            builder: (context, result) {
              print(result.date);
              return (Text(result.date));
            },
          ),

也许我遗漏了什么。当我写
print(result.date); 我的 Bloc class 它打印出来了。但是在 UI class 和 BlocBuilder 中什么都没有。当我调试它时,我看到:在 return 元素行工作之后,它不会跳转到 BlocBuilder,因为每个都在继续。但是当它完成时它仍然没有跳。也许我的架构或方法可能是错误的。我也乐于接受有关这些的建议。

总而言之,我无法在 bloc 生成器中将“流结果的列表元素”作为流一一获取。有人可以帮忙吗?

您还没有为您的 Bloc 定义状态。 你应该创建一个状态

class WeatherState
class WeatherLoaded extends WeatherState{
      final Weather weather;
  WeatherLoaded(this.weather);
}

那么您的 Bloc class 应该看起来像这样 WeatherEvent 和 WeatherState

class WeatherBloc extends Bloc<WeatherEvent, WeatherState> {
  WeatherBloc(Weather initialState) : super(initialState);

  @override
  Stream<Weather> mapEventToState(WeatherEvent event) async*{
    switch (event) {
      case WeatherEvent.getWeather:
        // Api call call that returns a weather object.
        final res = await WeatherRequest().fetchWeathers();
        yield WeatherLoaded(res);
        break;

      case WeatherEvent.getDetails:
        break;
    }
  }
}

接下来,您的 Bloc Builder 应该如下所示

         BlocBuilder<WeatherBloc, WeatherState>(
            builder: (context, WeatherState state) {
              if(state is WeatherLoaded) {
                return (Text(state.date));
              }
              
            },
          ),

您应该将 API 调用重写为 return 天气对象