【问题标题】:How to properly handle an array of json in Flutter?如何正确处理 Flutter 中的 json 数组?
【发布时间】:2021-06-30 06:24:30
【问题描述】:

所以基本上我是在 Flutter 中使用 http 包从 api 获取数据。 response.body 是一个如下所示的数组:

[
   {
      "id":1,
      "full_name":"Cristiano Ronaldo",
      "avatar":"http://localhost:8000/media/avatars/Ronaldo.jpeg",
      "created":"2021-06-30T02:25:56.332816Z"
   },
   {
      "id":2,
      "full_name":"Paul Pogba",
      "avatar":"http://localhost:8000/media/avatars/Pogba.jpeg",
      "created":"2021-06-30T02:49:17.649970Z"
   },
   {
      "id":3,
      "full_name":"Paulo Dybala",
      "avatar":"http://localhost:8000/media/avatars/Dybala.jpeg",
      "created":"2021-06-30T02:52:33.338296Z"
   },
   {
      "id":4,
      "full_name":"Leonel Messi",
      "avatar":"http://localhost:8000/media/avatars/Messi.jpeg",
      "created":"2021-06-30T02:53:39.539556Z"
   },
   {
      "id":5,
      "full_name":"Kylian Mbappe",
      "avatar":"http://localhost:8000/media/avatars/Mbappe.jpeg",
      "created":"2021-06-30T02:57:29.891686Z"
   }
]

我的问题是我想基本上将其格式化为“飞镖”方式。像这样的:

List players = response.body;

我得到的错误是这样的:

A value of type 'String' can't be assigned to a variable of type 'List<dynamic>'.
Try changing the type of the variable, or casting the right-hand type to 'List<dynamic>'.

为什么会出现这个错误。我知道列表已经正确格式化,并且 json 对象的键值对都是字符串,但我想将其格式化为“飞镖”方式。如果我这样做:

var players = response.body;

确实有效。我应该只使用 var 并称之为好还是应该格式化它?

附加问题: 如果我想在initState方法中调用方法从api获取数据,我会这样做吗:

Future<void> _getPlayers() async {
   ...
} 

void initState() {
   super.initState();
   _getPlayers();
}

谢谢!

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    有很多方法可以做到这一点

    最有效的方法是像这样制作Object

    class Player {
      final int id;
      final String fullName;
      final String avatar;
      final String created;
    
      const Player({this.id, this.fullName, this.avatar, this.created});
    
      Player.fromJson(Map<String, dynamic> json) {
        id = json['id'];
        fullName = json['full_name'];
        avatar = json['avatar'];
        created = json['created'];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data['id'] = this.id;
        data['full_name'] = this.fullName;
        data['avatar'] = this.avatar;
        data['created'] = this.created;
        return data;
      }
    }
    

    那你就可以增值了

    • 不是这样的
    List players = response.body
    
    • 你可以这样使用
    var data = json.decode(response.body);
    
    List<Player> players  = data.map((element){
       return Player.fromJson(element);
    }).toList();
    

    用于访问来自players 列表的数据

    • 你可以这样做
    players[0].fullName;
    players[1].fullName;
    

    【讨论】:

    • 嘿,我对扑扑还很陌生,所以我不太擅长。为什么你的解决方案是这样的?就像我接受的答案非常简单并且有效,但我看到很多人也这样做。为什么这是最好/正确的方法?
    • 通过为我们的 API 响应创建自定义 Dart class 非常有用,因为我们知道我们的变量从 API 接受什么样的数据,而且我们可以轻松地将测试规则添加到自定义类。初学者级别 - 自定义 class 有助于检查来自 API 的数据是否正确且符合我们的需要。这有助于避免不必要的应用程序崩溃或错误。希望你明白我的意思。
    • List players = jsonDecode(response.body); 在这种情况下,您不确定您的 players 列表将包含哪些数据。如果response.body 返回不需要的数据,您的players 列表也会得到错误的数据。因此,这将直接影响您显示来自players 列表的数据的位置。创建自定义类将有助于在分配给players 列表之前检查来自response.body 的数据。
    【解决方案2】:

    基本上,您是在尝试将 JSON 转换为列表而不对其进行解码,

    编码的 JSON 是这样的字符串

    "{ \"username\": \"ali\", \"number\": \"ali@gmail.com\" }"
    

    当你解码它时,它会变成这样的 List 或 Map

    { 
       "username": "ali",
       "email": "ali@gmail.com"
    }
    

    因此,要修复您的代码,您需要对 json 进行解码,然后将其转换为列表

    List players = jsonDecode(response.body);
    

    ...

    侧面回答:

    是的,您可以这样做,但这会在页面之间导航时导致异常(假设您向服务器发送了一个请求,当数据到来时,您必须 setState 小部件,但即使小部件已释放并且您导航到其他页面,您的方法将在未安装的小部件上调用 setState,这将导致异常)

    因此,如果您不打算使用依赖管理库,那么只需使用未来的构建器

    【讨论】:

    • 这绝对不是最好的答案
    【解决方案3】:

    将此添加到您的代码中:

    import 'dart:convert';
    

    那么,

    var players = jsonDecode(response.body);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-29
      • 1970-01-01
      • 2021-08-09
      • 2018-04-01
      • 2014-07-25
      • 2021-04-25
      • 1970-01-01
      • 2021-07-26
      相关资源
      最近更新 更多