首页 > 解决方案 > 嵌套json数据的序列化

问题描述

我正在尝试学习颤振,但我被困在 JSON 序列化中。我正在关注 YouTube 和颤振文档中的一些教程,但我在序列化方面遇到了一些困难。你能帮我一点吗,这是出于教育目的,所以我对背后的理论而不是解决方案本身更感兴趣,但是即使只有解决方案,我认为我也可以尝试理解这个过程。我应该提到我知道这一点,但就我而言,我在数据中嵌套了对象,这让我感到困惑。

响应数据样本,它基本上是一家商店,每天都有一个营业日列表,每个对象(天)都有营业时间和日期。

{
    "data": [
        {
            "openTime": {
                "open": "10:00",
                "close": "20:00"
            },
            "date": {
                "gregorian": {
                    "day": "01",
                    "weekday": {
                        "en": "Friday",
                        "de": "Freitag"
                    },
                    "month": {
                        "number": 5,
                        "en": "May",
                        "de": "Mai"
                    },
                    "year": "2020"
                }
            }
        },
        {
            "openTime": {
                "open": "12:00",
                "close": "18:00"
            },
            "date": {
                "gregorian": {
                    "day": "02",
                    "weekday": {
                        "en": "Saturday",
                        "de": "Samstag"
                    },
                    "month": {
                        "number": 5,
                        "en": "May",
                        "de": "Mai"
                    },
                    "year": "2020"
                }
            }
        }
    ]
}

我获取数据的函数:

Future<Mall> fetchData() async {
  final response = await http.get(url);
  if (response.statusCode == 200) {
    return Mall.fromJson(json.decode(response.body));
  } else {
    throw Exception('Failed to load data!');
  }
}

就我而言, Mall 类有openTimeand date,我认为这是我的问题所在。

class Mall {
  final dynamic openTime;
  final dynamic date;

  Mall({this.openTime, this.date});

  factory Mall.fromJson(Map<String, dynamic> json) {
    return Mall(openTime: json['openTime'], date: json['date']);
  }
}

我试图产生的结果应该是这样的,所以我可以遍历数据列表并构建一张卡片数天(例如过去 7 天)

var time = [
  {
    "openTime": {"open": "10:00", "close": "20:00"},
    "date": "01 May 2020"
  },
  {
    "openTime": {"open": "12:00", "close": "18:00"},
    "date": "02 May 2020"
  },
];

我得到的错误是:

type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>'

如果您需要更多详细信息,请告诉我。提前致谢。

标签: flutterdart

解决方案


您的代码中有一些错误。

1-在这一部分中,您的响应是容器对象中的对象,称为“数据”

Future<Mall> fetchData() async {
  final response = await http.get(url);
  if (response.statusCode == 200) {
    return Mall.fromJson(json.decode(response.body));  //here
  } else {
    throw Exception('Failed to load data!');
  }
}

2-您的购物中心数据是“数据”中的嵌套对象,因此将您的购物中心类自定义为

class Mall {
    List<Datum> data;

    Mall({
        this.data,
    });

    factory Mall.fromJson(Map<String, dynamic> json) => Mall(
        data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
    );

    Map<String, dynamic> toJson() => {
        "data": List<dynamic>.from(data.map((x) => x.toJson())),
    };
}

class Datum {
    OpenTime openTime;
    Date date;

    Datum({
        this.openTime,
        this.date,
    });

    factory Datum.fromJson(Map<String, dynamic> json) => Datum(
        openTime: OpenTime.fromJson(json["openTime"]),
        date: Date.fromJson(json["date"]),
    );

    Map<String, dynamic> toJson() => {
        "openTime": openTime.toJson(),
        "date": date.toJson(),
    };
}

class Date {
    Gregorian gregorian;

    Date({
        this.gregorian,
    });

    factory Date.fromJson(Map<String, dynamic> json) => Date(
        gregorian: Gregorian.fromJson(json["gregorian"]),
    );

    Map<String, dynamic> toJson() => {
        "gregorian": gregorian.toJson(),
    };
}

class Gregorian {
    String day;
    Weekday weekday;
    Month month;
    String year;

    Gregorian({
        this.day,
        this.weekday,
        this.month,
        this.year,
    });

    factory Gregorian.fromJson(Map<String, dynamic> json) => Gregorian(
        day: json["day"],
        weekday: Weekday.fromJson(json["weekday"]),
        month: Month.fromJson(json["month"]),
        year: json["year"],
    );

    Map<String, dynamic> toJson() => {
        "day": day,
        "weekday": weekday.toJson(),
        "month": month.toJson(),
        "year": year,
    };
}

class Month {
    int number;
    String en;
    String de;

    Month({
        this.number,
        this.en,
        this.de,
    });

    factory Month.fromJson(Map<String, dynamic> json) => Month(
        number: json["number"],
        en: json["en"],
        de: json["de"],
    );

    Map<String, dynamic> toJson() => {
        "number": number,
        "en": en,
        "de": de,
    };
}

class Weekday {
    String en;
    String de;

    Weekday({
        this.en,
        this.de,
    });

    factory Weekday.fromJson(Map<String, dynamic> json) => Weekday(
        en: json["en"],
        de: json["de"],
    );

    Map<String, dynamic> toJson() => {
        "en": en,
        "de": de,
    };
}

class OpenTime {
    String open;
    String close;

    OpenTime({
        this.open,
        this.close,
    });

    factory OpenTime.fromJson(Map<String, dynamic> json) => OpenTime(
        open: json["open"],
        close: json["close"],
    );

    Map<String, dynamic> toJson() => {
        "open": open,
        "close": close,
    };
}

现在您可以像以前一样获取商城数据了

Future<Mall> fetchData() async {
  final response = await http.get(url);
  if (response.statusCode == 200) {
    return Mall.fromJson(json.decode(response.body));  //here
  } else {
    throw Exception('Failed to load data!');
  }
}

推荐阅读