如何将父对象中的自定义对象列表转换为(和自)JSON?

How can I convert a list of custom objects within a parent object to (and from) JSON?

我有一个应用程序,我在其中尝试将用户输入的自定义对象与 JSON 相互转换,以便我可以将它们存储在共享首选项中。

每个对象都是一个 'Resolution' 并且有多种 属性 类型(日期、颜色等...),我可以轻松转换。到目前为止一切顺利...

我的问题是它的属性之一是 'Commitment' 类型的列表。 'Commitment' 是另一个自定义对象,它还具有许多不同类型的属性(日期、双精度、字符串等)。

我发现我不能简单地将整个列表 属性 转换成一个字符串并返回,我需要 运行 对列表中每个承诺中的所有单个属性进行特定转换.

所以我基本上有一个嵌套转换需求...

我的'RESOLUTION'代码如下

  class Resolution {
  final String id;
  String title;
  late DateTime? startDate;
  late DateTime? endDate;
  Color color;
  double progress;
  List<Commitment> commitments;
  bool isComplete;

  Resolution(
      {required this.id,
      required this.title,
      this.startDate,
      required this.endDate,
      this.color = Colors.orange,
      this.progress = 0,
      this.commitments = const [],
      this.isComplete = false});

  Map toMap() {
    return {
      'id': id,
      'title': title,
      'startDate': startDate!.toIso8601String(),
      'endDate': endDate!.toIso8601String(),
      'color': color.value.toString(),
      'progress': progress,
      'commitments': convertCommitmentsToJSON(commitments),
      'isComplete': isComplete,
    };
  }

  Resolution.fromMap(Map map)
      : id = map['id'],
        title = map['title'],
        startDate = DateTime.tryParse(map['startDate']),
        endDate = DateTime.tryParse(map['endDate']),
        color = Color(int.parse(map['color'])),
        progress = map['progress'],
        commitments = List<Commitment>.from(map['commitments']),
        isComplete = map['isComplete'];

  convertCommitmentsToJSON(commitments) {
    for (Commitment commitment in commitments) {
      commitment.toMap();
    }
  }

除了列表承诺外,这非常有效属性...如您所见,我编写了以下方法

  convertCommitmentsToJSON(commitments) {
    for (Commitment commitment in commitments) {
      commitment.toMap();
    }
  }

我认为通过遍历列表内容并应用我在 COMMITMENT class.

中创建的转换方法,成功将列表转换为 JSON

假设我已经解决了一半的问题(我可能不太愿意插手),我的问题是将 JSON 转换回 Commitment 对象列表...

我尝试了以下...

  convertCommitmentsFromJSON(List<Commitment> list) {
    for (Commitment commitment in list) {
      commitment.fromMap(jsonDecode(commitment));
    }
  }

...但我收到消息“无法通过实例访问静态方法 'fromMap'”

我的(简体)COMMITMENTclass内容如下,如果有帮助的话

class Commitment {
  String description;
  DateTime? endDate;

  Commitment({required this.description, this.endDate});

  Map<String, dynamic> toMap() => {
        'description': description,
        'endDate': endDate?.toIso8601String(),
      };

  static Commitment fromMap(Map<String, dynamic> json) => Commitment(
        description: json['description'],
        endDate: DateTime.tryParse(json['endDate']),
      );
}

有人可以帮忙吗?我对编码比较陌生,所以也许我完全走错了路


修改后的转换代码

Map toJson() {
    return {
      'id': id,
      'title': title,
      'startDate': startDate!.toIso8601String(),
      'endDate': endDate!.toIso8601String(),
      'color': color.value.toString(),
      'progress': progress,
      'commitments': convertCommitmentsToJSON(commitments),
      'isComplete': isComplete,
    };
  }

  Resolution.fromJson(Map map)
      : id = map['id'],
        title = map['title'],
        startDate = DateTime.tryParse(map['startDate']),
        endDate = DateTime.tryParse(map['endDate']),
        color = Color(int.parse(map['color'])),
        progress = map['progress'],
        commitments = convertCommitmentsFromJSON(List<Commitment>.from(map['commitments'])),
        isComplete = map['isComplete'];

  convertCommitmentsToJSON(commitments) {
    for (Commitment commitment in commitments) {
      commitment.toJson();
    }
  }

   
  convertCommitmentsFromJSON(List<Commitment> list) {
    for (Commitment commitment in list) {
      Commitment.fromJson;
    }
  }

要访问静态函数,您需要使用 class 名称,而不是实例

Commitment.fromMap(jsonDecode(commitment));

仅供参考:惯例是 fromJsontoJson

此外:最好使 fromMap 成为工厂构造函数……再说一次,惯例。

factory Commitment.fromJson(Map<String, dynamic> json) => Commitment(
        description: json['description'],
        endDate: DateTime.tryParse(json['endDate']),
      );

在凯文的帮助下最终得以解决。除了语法之外,我缺少的一个关键是我实际上并没有返回这个函数的原始版本中的列表。我只是循环遍历,对输出什么也不做。

凯文,感谢您的协助。终于到了! ;)

  static List<Commitment> convertCommitmentsFromJSON(List<dynamic> list) {
    List<Commitment> commitmentsList = [];
    if (list.isNotEmpty) {
      for (var item in list) {
        Commitment commitment = Commitment.fromJson(item);
        commitmentsList.add(commitment);
      }
    }
    return commitmentsList;
  }