如何在Dart中创建可转换为JSON的类

3
这个问题与这篇文章有关。
我尝试了以下代码:
import 'dart:convert';

/*server side Post class */
class Post {
  int post_id;
  String title;
  String description;
  DateTime posted_at;
  DateTime last_edited;
  String user;
  String editor;
  int up_votes;
  int down_votes;
  int total_votes;
  String links_to;
  List<String> tags = new List();

  Post.fromSQL(List sql_post) {
     //initialization code, unrelated.
  }

  Map toJson(){
    Map fromObject = {
      'post_id' : post_id,
      'title' : title,
      'description' : description,
      'posted_at' : posted_at,
      'last_edited' : last_edited,
      'user' : user,
      'editor' : editor,
      'up_votes' : up_votes,
      'dwon_votes' : down_votes,
      'total_votes' : total_votes,
      'links_to' : links_to,
      'tags' : tags
    };

    return fromObject;
    //I use the code below as a temporary solution
    //JSON.encode(fromObject, toEncodable: (date)=>date.toString());
  }
}

我有一个临时解决方案,但我真的希望能够做到以下:

JSON.encode(posts, toEncodable: (date)=>date.toString())

在这里,posts是一个帖子对象列表。我期望它可以转换成一个 Post 类的 JSON 表示形式列表。但实际得到的是一个由字符串“Instance of 'Post'”组成的列表。

那么问题来了,是语法不再支持,还是我该采取其他策略呢?

1个回答

5
似乎你只能使用toEncodable:toJson()的回退方法之一。
如果你将日期包装在一个提供toJson()方法的类中,就不需要使用toEncodable:了。
class JsonDateTime {
  final DateTime value;
  JsonDateTime(this.value);

  String toJson() => value != null ? value.toIso8601String() : null;
}

class Post {
  ...
  Map toJson() => {
    'post_id' : post_id,
    'title' : title,
    'description' : description,
    'posted_at' : new JsonDateTime(posted_at),
    'last_edited' : new JsonDateTime(last_edited),
    'user' : user,
    'editor' : editor,
    'up_votes' : up_votes,
    'dwon_votes' : down_votes,
    'total_votes' : total_votes,
    'links_to' : links_to,
    'tags' : tags
  };
}

或者,您可以确保您的toEncodeable:处理每种不受支持的类型:

print(JSON.encode(data, toEncodable: (value) {
  if (value is DateTime) {
    return value.toIso8601String();
  } else {
    return value.toJson();
  }
}));

我误解了文档。我认为toEncodable是在toJson()返回的对象的那些不可编码的子元素上运行的。最终,我通过稍微更改Map来解决了这个问题:'posted_at' : posted_at.toIso8601String(), 'last_edited' : last_edited.toIso8601String(),并完全删除了toEncodable - Lukasz
那会很好,但似乎并非如此。当然,这也是一个不错的解决方案。 - Günter Zöchbauer
1
toEncodable 函数是要使用的函数,没有其他无法编码对象的备选方案。如果您没有提供另一个函数,则 toJson 调用只是默认的 toEncodable 函数。 - lrn

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