我正在尝试将对象"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,
};
}
我用了这个:
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);
但问题是我得到这个结果:
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)
jsonEncode 需要一个Map<String, dynamic>
,而不是一个Week
对象。调用toJson()
方法应该可以解决问题。
var json = jsonEncode(week.toJson());
但是,请记住,您的toJson()
方法也是不正确的,因为_goalList和日期之类的东西仍然是对象,而不是地图或列表。您还需要在这些方法上实现 toJson 方法。
要回答您的具体问题:
- 因为dart不是javascript/打字稿。Dart 在运行时检查类型,因此您必须明确告诉它如何转换事物 - Dart 中也没有反射,因此它无法自行弄清楚。
- 您可以使用使用代码生成的库自动为您执行这些操作 - 尽管在运行时仍然无法实现 - 阅读有关 JSON 序列化的更多信息。
- 最简单的方法是直接在类中实现方法,因为这是您可以在根对象中访问的位置。请记住,
jsonEncode
需要的结构是Map<String, dynamic>
,但dynamic
部分实际上意味着List<dynamic>
,Map<String, dynamic>
或与json兼容的原语,例如String
或double
- 如果你试着想象这种嵌套结构的这种类型是什么样子的,你会意识到它基本上是json。因此,当你做类似'goalList': _goalList,
的事情时,你给它一个对象,这不是允许的类型之一。
希望这能把事情弄清楚一点。
对于任何想知道的人:我得到了我的解决方案。
为了使我的代码正常工作,我还需要在类Goal
中实现toJson()
方法(因为我在Week
中使用了List<Goal>
)。
class Goal{
String _text;
bool _reached;
Map<String, dynamic> toJson() =>
{
'text': _text,
'reached': _reached,
};
}
此外,我需要向DateTime
对象添加.toIso8601String()
,就像Week
类中的对象一样:
Map<String, dynamic> toJson() =>
{
'startDate': _startDate.toIso8601String(),
'endDate': _endDate.toIso8601String(),
'goalList': _goalList,
'improvement': _improvement,
};
现在输出为:
{"startDate":"2019-05-27T00:00:00.000Z","endDate":"2019-06-02T00:00:00.000Z","goalList":[],"improvement":""}
从上面 @Phillip 的 Json 序列化答案中获取建议 2,我相信您可以跳过@JsonSerializable
注释并只使用@Freezed
注释,因为 Freezed"将自动要求json_serializable从 Json/toJson 生成所有必要的内容。 所以这里的例子:https://flutter.dev/docs/development/data-and-backend/json#use-code-generation-for-medium-to-large-projects 成为:
//import 'package:json_annotation/json_annotation.dart';
import 'freezed_annotation/freezed_annotation.dart';
/// This allows the `User` class to access private members in
/// the generated file. The value for this is *.g.dart, where
/// the star denotes the source file name.
part 'user.g.dart';
part 'user.freezed.dart';
/// An annotation for the code generator to know that this class needs the
/// JSON serialization logic to be generated.
@freezed
class User {
User(this.name, this.email);
String name;
String email;
/// A necessary factory constructor for creating a new User instance
/// from a map. Pass the map to the generated `_$UserFromJson()` constructor.
/// The constructor is named after the source class, in this case, User.
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
/// `toJson` is the convention for a class to declare support for serialization
/// to JSON. The implementation simply calls the private, generated
/// helper method `_$UserToJson`.
Map<String, dynamic> toJson() => _$UserToJson(this);
}
冻结:https://pub.dev/packages/freezed 不要忘记编辑pubspec.yaml
以进行freezed
和freezed_annotation