如何在 Dart 的 Future 函数中从 JSON 创建一个类对象?

4

我的主要问题是下面的代码对我来说运行良好,但它不是优化过的。我有一个包含以下MySQL请求的PHP文件:

if("GET_CLIENT" == $action){
   $code = $_POST['code'];
   $db_data = array();
   $sql = "SELECT  `nom` , `prenom`, `age` FROM `client` WHERE `code` LIKE '$code'" ;
   $result = $conn->query($sql);
    $row = $result->fetch_assoc())
    echo json_encode($db_data);
   $conn->close();
   return;}

在我的 Dart 应用程序中,我有以下类Client
  class Client {
  String code;
  String nom;
  String prenom;
  Client({this.code, this.prenom, this.nom });

  factory Client.fromJson(Map<String, dynamic> json) {
    return Client(
      code: json['code'] as String,
      nom: json['nom'] as String,
      prenom: json['prenom'] as String, ); }  }

现在我有如下Future函数来从数据库中获取返回的单行数据:

Future<Client> fetchClient(String code) async {
  var map = Map<String, dynamic>();
  map['action'] = 'GET_CLIENT';
  map['code'] = code;
  var response = await http.post(uri, body: map);
  if (response.statusCode == 200) {
    final items = json.decode(response.body).cast<Map<String, dynamic>>();
    List<Client> listOfClients = items.map<Client>((json) {
      return Client.fromJson(json);
    }).toList();
    print(listOfClients.first.code);
    return listOfClients.first;
  } else {
    throw Exception('Failed to load data.');
  }
}

这对我来说很好用,但正如你所看到的,Future函数正在创建客户列表,而这个列表当然只有一个项目,所以我使用了return listOfClients.first;。现在我的问题是如何优化我的Future函数,使其仅返回一个客户,如下所示:

if (response.statusCode == 200) {
    final items = json.decode(response.body).cast<Map<String, dynamic>>();
      Client client = .. somthing ??
     // instead of List Client 
    return client; // instead of return listOfClients.first
   }

提示:这篇文章的标题有点令人困惑,请编辑提出改建议。


1
问题是,这段代码能否为多个客户端重复使用? - farouk osama
1
如果你的答案是否定的,就像我在我的回答中所说的那样,你必须修改查询。 - farouk osama
1
$sql = "SELECT nom, prenom, age FROM client WHERE code LIKE '$code limit 1'"; - farouk osama
1个回答

5
如果 Get_only_one_situation 方法编写正确,它应该只返回一个值,你只需要像这样进行解码:
const uri = 'http://10.0.2.2/re/App_agent/agent.php';
      Future<Situation> fetchOneSituation(String ID) async {
            var map = Map<String, dynamic>();
            map['action'] = 'Get_only_one_situation';
            map['ID'] = ID;
       var response = await http.post(uri, body: map);
        if (response.statusCode == 200) {
          return Situation.fromJson(json.decode(response.body));
          // You probably need this
          // return Situation.fromJson(json.decode(response.body)['data'])
        } else {
          throw Exception('Failed to load data.');
        }
      }

在你更新问题后,我明白了你正在使用这个操作Get_only_one_situation获取所有的部门,这不是首选方法。

如果必须获取整个表格,则只需使用firstWhere方法获取相应的项,像这样:

Future<Situation> fetchSituation(String ID) async {
  var map = Map<String, dynamic>();
  map['action'] = 'Get_only_one_situation'; 
  var response = await http.post(uri, body: map);
  if (response.statusCode == 200) {
    final items = json.decode(response.body).cast<Map<String, dynamic>>();
    List<Situation> listOfSituations = items.map<Client>((json) {
      return Situation.fromJson(json);
    }).toList();
    return listOfSituations.firstWhere((item)=>item.ID==item.ID);
  } else {
    throw Exception('Failed to load data.');
  }
}

当然,我不建议使用此方法,因为在数据库上查询比在Flutter中的代码快,特别是处理大量数据时。

Salam,感谢你的帮助兄弟,我更新了我的帖子,我相信它有点误导或令人困惑,更新将有助于给我提供解决方案。请更新你的答案,因为你现在对我的问题有更多的信息。 - Asmoun
以下代码看起来正是我想要的,但它无法工作:return Client.fromJson(json.decode(response.body)); - Asmoun
1
我没有 PHP 经验,但你只需要返回一个对象而不是对象列表就可以让它工作。 - farouk osama
1
看起来你正在以以下形式返回值:[{"id":1,"name":"example"}],正确的形式是 {"id":1,"name":"example"},不需要 []。 - farouk osama
是的,我认为那就是问题所在。 - Asmoun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接