Вложенный объект в Dart
JSON умеет вкладывать объекты друг в друга через
вложенные фигурные скобки. В Dart для этого
объявляют свойство с типом другого класса и
в toJson вызывают запись вложенного
значения, а в fromJson - разбор карты
внутреннего объекта.
Адрес и контакт клиента логично разделить: сначала
тип для города и индекса, затем тип заказа с полем
адреса. У обоих классов есть toJson
и fromJson:
class GeoPoint {
GeoPoint(this.city, this.postal);
final String city;
final String postal;
Map<String, Object?> toJson() => {
'city': city,
'postal': postal,
};
factory GeoPoint.fromJson(Map<String, Object?> json) {
return GeoPoint(
json['city'] as String,
json['postal'] as String,
);
}
}
class ClientOrder {
ClientOrder(this.id, this.shipTo);
final int id;
final GeoPoint shipTo;
Map<String, Object?> toJson() => {
'id': id,
'shipTo': shipTo.toJson(),
};
factory ClientOrder.fromJson(Map<String, Object?> json) {
return ClientOrder(
json['id'] as int,
GeoPoint.fromJson(
json['shipTo'] as Map<String, Object?>,
),
);
}
}
Запись в строку собирает один JSON-объект, где
значение shipTo само является объектом
с ключами city и postal:
import 'dart:convert';
class GeoPoint {
GeoPoint(this.city, this.postal);
final String city;
final String postal;
Map<String, Object?> toJson() => {
'city': city,
'postal': postal,
};
factory GeoPoint.fromJson(Map<String, Object?> json) {
return GeoPoint(
json['city'] as String,
json['postal'] as String,
);
}
}
class ClientOrder {
ClientOrder(this.id, this.shipTo);
final int id;
final GeoPoint shipTo;
Map<String, Object?> toJson() => {
'id': id,
'shipTo': shipTo.toJson(),
};
factory ClientOrder.fromJson(Map<String, Object?> json) {
return ClientOrder(
json['id'] as int,
GeoPoint.fromJson(
json['shipTo'] as Map<String, Object?>,
),
);
}
}
var order = ClientOrder(
501,
GeoPoint('Oslo', '0150'),
);
print(jsonEncode(order.toJson()));
Чтение из текста работает в обратном порядке: сначала
разбирается внешний объект, затем вложенный блок
для GeoPoint. Если у внутреннего типа
нет fromJson, цепочку разбора не
завершить.
Объявите класс DurationSlot
с полями hours и minutes,
затем MeetingPlan с title и
slot типа DurationSlot.
Запишите план с названием "sync"
и длительностью 1 час 30
минут в JSON и выведите строку.
Из текста
{"title":"demo","slot":{"hours":0,"minutes":45}}
восстановите MeetingPlan и выведите
название и суммарные минуты как одно число
45.