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

Posted

技术标签:

【中文标题】Flutter 使用 BloC 模式从 API 结果中获取列表元素【英文标题】:Flutter get list elements from API result with BloC Pattern 【发布时间】:2020-11-19 21:28:55 【问题描述】:

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

我在响应类中将其格式化为天气模型。

天气模型类

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 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 类时,它会打印出来。但是在 UI 类和 BlocBuilder 中什么都没有。当我调试它时,我看到:在返回元素行工作之后,它不会跳转到 BlocBuilder,因为每个都在继续。但是当它完成时它仍然没有跳跃。也许我的架构或方法可能是错误的。我也愿意接受有关这方面的建议。

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

【问题讨论】:

正如@tayomi 所说,您应该使用 bloc 扩展您的天气块。如果您需要参考 bloc 使用情况,请随意浏览我的 repo 【参考方案1】:

您尚未为您的 Bloc 定义状态。 你应该创建一个状态

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

那么你的 Bloc 类应该看起来像这样 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 调用来返回一个 Weather 对象

【讨论】:

感谢您的回答和解释。有效。现在我也能理解“状态逻辑”了。 很高兴它为你工作@burcus。请考虑为答案投票,以便其他人可以找到它。

以上是关于Flutter 使用 BloC 模式从 API 结果中获取列表元素的主要内容,如果未能解决你的问题,请参考以下文章

Flutter Bloc 与新闻 api

Flutter BLoC 模式 - 如何在流事件后导航到另一个屏幕?

Flutter中带有bloc的无限列表(表示层中的列表长度不变)

将flutter_bloc与tabview一起使用

如何使用 bloc 并在 dart 中手动侦听 bloc.state 而不是通过 Flutter 或 AngularDart 的 bloc 管道?

Bloc 模式是不是适合在 Flutter 应用中管理导航?