如何在 Flutter 中将对象编码为 json

laa*_*IGL 26 json dart flutter

我正在尝试将对象“Week”转换为 json。

https://flutter.dev/docs/development/data-and-backend/json这是我使用的源

class Week{
  DateTime _startDate;
  DateTime _endDate;
  List<Goal> _goalList;
  String _improvement;

  Week(this._startDate, this._endDate){
    this._goalList = List<Goal>();
    this._improvement = "";
  }

  Week.fromJson(Map<String, dynamic> json)
    : _startDate =  json['startDate'],
      _endDate = json['endDate'],
      _goalList = json['goalList'],
      _improvement = json['improvement'];

  Map<String, dynamic> toJson() => 
  {
    'startDate': _startDate,
    'endDate': _endDate,
    'goalList': _goalList,
    'improvement': _improvement,
  };
}
Run Code Online (Sandbox Code Playgroud)

我用过这个:

DateTime startDate = currentDate.subtract(new Duration(days:(weekday-1)));
DateTime endDate = currentDate.add(new Duration(days:(7-weekday)));

Week week = new Week(startDate, endDate);
var json = jsonEncode(week);
Run Code Online (Sandbox Code Playgroud)

但问题是我得到了这个结果:

Unhandled Exception: Converting object to an encodable object failed: Instance of 'Week'
#0      _JsonStringifier.writeObject (dart:convert/json.dart:647:7)
#1      _JsonStringStringifier.printOn (dart:convert/json.dart:834:17)
#2      _JsonStringStringifier.stringify (dart:convert/json.dart:819:5)
#3      JsonEncoder.convert (dart:convert/json.dart:255:30)
#4      JsonCodec.encode (dart:convert/json.dart:166:45)
#5      jsonEncode (dart:convert/json.dart:80:10)
Run Code Online (Sandbox Code Playgroud)

Phi*_*ann 34

jsonEncode 需要一个Map<String, dynamic>,而不是一个Week对象。调用您的toJson()方法应该可以解决问题。

var json = jsonEncode(week.toJson());
Run Code Online (Sandbox Code Playgroud)

但是,请记住,您的toJson()方法也是不正确的,因为诸如 _goalList 和日期之类的东西仍然是对象,而不是 Maps 或 Lists。您还需要在这些方法上实现 toJson 方法。

要回答您的具体问题:

  1. 因为 dart 不是 javascript / typescript。Dart 在运行时检查类型,因此您必须明确告诉它如何转换事物 - 在 dart 中也没有反射,因此它无法自行解决。
  2. 您可以使用一个使用代码生成的库来自动为您执行这些操作——但在运行时仍然无法实现——阅读有关JSON 序列化的更多信息。
  3. 最简单的方法是直接在类中实现方法,因为这是您可以在根对象中访问的地方。请记住,jsonEncode需要的结构是 a Map<String, dynamic>,但该dynamic部分的真正含义是List<dynamic>Map<String, dynamic>或者是与 json 兼容的原语,例如Stringor double- 如果您尝试想象所述类型的这种嵌套结构的外观,您会意识到它基本上是json。因此,当您执行类似操作时,'goalList': _goalList,您将给它一个对象,这不是允许的类型之一。

希望这能让事情变得更清楚。


laa*_*IGL 13

对于任何想知道的人:我得到了我的解决方案。

为了使我的代码工作,我还需要toJson()在我的类中实现这些方法Goal(因为我List<Goal>在 中使用Week)。

class Goal{
  String _text;
  bool _reached;

  Map<String, dynamic> toJson() =>
  {
    'text': _text,
    'reached': _reached,
  }; 
}
Run Code Online (Sandbox Code Playgroud)

另外,我需要添加.toIso8601String()到类中的DateTime对象中Week

Map<String, dynamic> toJson() => 
  {
    'startDate': _startDate.toIso8601String(),
    'endDate': _endDate.toIso8601String(),
    'goalList': _goalList,
    'improvement': _improvement,
  };
Run Code Online (Sandbox Code Playgroud)

现在输出是:

 {"startDate":"2019-05-27T00:00:00.000Z","endDate":"2019-06-02T00:00:00.000Z","goalList":[],"improvement":""}
Run Code Online (Sandbox Code Playgroud)