我想将“ Box”对象的列表转换为json文件,然后又将其读回(将json文件转换为“ Box”对象的列表),但是我对实现有些困惑。我已经编写了以下代码,但是我只能将单个“ Box”对象写入json并将其转换回单个“ Box”对象。当我尝试使用列表执行此操作时,我遇到了一些错误,例如数据被覆盖或仅返回一个对象。
简而言之,我想将一个List写入json并将json转换为List
我具有以下数据结构
盒子模型
class Box {
final String nameBox;
final List<Item> items;
Box({@required this.nameBox, @required this.items});
factory Box.fromJson(Map<String, dynamic> json) {
var items = json['items'];
List<Item> itemsList = items.cast<Item>();
return new Box(
nameBox: json["nameBox"],
items: itemsList
);
}
Map<String, dynamic> toJson() => {
"nameBox": nameBox,
"items": items,
};
}
Box fromJson(String boxData) {
return Box.fromJson(json.decode(boxData));
}
String toJson(Box box) {
return json.encode(box.toJson());
}
项目模型
class Item {
final String itemName;
final int quantity;
Item({@required this.itemName, @required this.quantity});
factory Item.fromJson(Map<String, dynamic> json) {
return new Item(itemName: json["itemName"], quantity: json["quantity"]);
}
Map<String, dynamic> toJson() => {
"itemName": itemName,
"quantity": quantity,
};
}
Item fromJson(String itemData) {
return Item.fromJson(json.decode(itemData));
}
String toJson(Item item) {
return json.encode(item.toJson());
}
writeToJson函数
Future writeJson(Box box) async {
final file = await _localFile;
List<Box> tempRead = await returnBoxes();
if (tempRead.isEmpty || tempRead == null) {
return;
}
tempRead.add(box);
file.writeAsString(json.encode(tempRead));
}
readJson函数
Future<List<Box>> returnBoxes() async {
final file = await _localFile;
List<Box> boxList = new List<Box>();
Map<String, dynamic> content = await json.decode(file.readAsStringSync());
boxList.add(Box.fromJson(content));
return boxList;
}
我还尝试将json内容转换为列表,但随后遇到一些可迭代的错误。有谁能帮助我吗?
答案 0 :(得分:0)
JSON具有这种特质,即所有东西都是对象或数组,并且您不知道要得到什么,除非对其进行解码。 Dart将这两种json类型分别解码为Map<String, dynamic>
和List<dynamic>
。 (之所以得到dynamic
是因为它们各自可以递归地成为值,json数组或json对象。)
Dart通过在其上调用toJson
对Dart对象进行编码,并通过发出[
然后使列表中的每个成员然后是]
来对Dart列表进行编码。
知道这一点,对数组/列表进行编码和解码很容易。 (我删除了所有不必要的代码。)
class Box {
final String nameBox;
final List<Item> items;
Box({@required this.nameBox, @required this.items});
factory Box.fromJson(Map<String, dynamic> json) => Box(
nameBox: json['nameBox'],
items: json['items'].map<Item>((e) => Item.fromJson(e)).toList(),
);
Map<String, dynamic> toJson() => {
'nameBox': nameBox,
'items': items,
};
}
class Item {
final String itemName;
final int quantity;
Item({@required this.itemName, @required this.quantity});
factory Item.fromJson(Map<String, dynamic> json) => Item(
itemName: json['itemName'],
quantity: json['quantity'],
);
Map<String, dynamic> toJson() => {
'itemName': itemName,
'quantity': quantity,
};
}
Future writeJson(Box box) async {
final file = await _localFile;
var boxes = await returnBoxes();
/* I think you probably don't want this...
if (boxes.isEmpty || boxes == null) {
return;
}*/
// but rather, this
if (boxes == null) boxes = [];
boxes.add(box);
await file.writeAsString(json.encode(boxes));
}
Future<List<Box>> returnBoxes() async {
final file = await _localFile;
// because the json is an array (i.e. enclosed in []) it will be decoded
// as a Dart List<dynamic>
List<dynamic> d = json.decode(await file.readAsString());
// here we map the List<dynamic> to a series of Box elements
// each dynamic is passed to the Box.fromJson constructor
// and the series is formed into a List by toList
return d.map<Box>((e) => Box.fromJson(e)).toList();
}