将带有数组的对象列表与json文件相互转换

时间:2019-06-10 08:24:49

标签: flutter dart

我想将“ 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内容转换为列表,但随后遇到一些可迭代的错误。有谁能帮助我吗?

1 个答案:

答案 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();
}