JsonSerializable:如何toJson/fromJson对应子类类型?
JsonSerializable: How to toJson/fromJson correspond to subclass type?
假设我有这样的数据结构
@JsonSerializable(explicitToJson: true)
class CartItem {
final Product product;
...
}
@JsonSerializable()
class Product {
final String id;
...
}
@JsonSerializable()
class Food extends Product {
final String foodName;
...
}
@JsonSerializable()
class Furniture extends Product {
final String furnitureName;
...
}
我想要的是当我使用 CartItem.toJson()
时它导出到 Json 映射对应于 Product
的类型。
例如
var x = CartItem(
product: Food(
id: '1100112',
foodName: 'Hamburger',
),
)
print(x.toJson());
这应该导致
{
'product': {
'id': '1100112',
'foodName': 'Hamburger',
}
}
同样在使用 fromJson
时,产品的类型为 Food
x.fromJson(x.toJson()) as Food //This should not error
我假设您正在使用包 json_serialization
。对于每个 class,您需要定义以下一些方法:
例如:
factory CartItem.fromJson(Map<String, dynamic> json) => _$CartItemFromJson(json);
Map<String, dynamic> toJson() => _$CartItemToJson(this);
然后你会运行生成命令行:
flutter pub run build_runner build
这将 auto-generate 一个 .g.dart
文件对应于您的
模型文件。
参考:https://pub.dev/packages/json_serializable
否则,如果您希望手动定义方法:
class CartItem {
final Product product;
CartItem({required this.product});
/// fromJson
factory CartItem.fromJson(Map<String, dynamic> json) => CartItem(
product: Product.fromJson(json["product"])
);
/// toJson
Map<String, dynamic> toJson() => {
"product": product.toJson()
};
}
class Product {
final String id;
Product({required this.id});
/// fromJson
factory Product.fromJson(Map<String, dynamic> json) => Product(
id: json["id"]
);
/// toJson
Map<String, dynamic> toJson() => {
"id": id
};
}
class Food extends Product {
final String foodName;
Food({required String id, required this.foodName}) : super(id: id);
/// fromJson
factory Food.fromJson(Map<String, dynamic> json) => Food(
id: json["id"],
foodName: json["foodName"]
);
/// toJson
@override
Map<String, dynamic> toJson() => {
"id": id,
"foodName": foodName
};
}
class Furniture extends Product {
final String furnitureName;
Furniture({required String id, required this.furnitureName}) : super(id: id);
/// fromJson
factory Furniture.fromJson(Map<String, dynamic> json) => Furniture(
id: json["id"],
furnitureName: json["furnitureName"]
);
/// toJson
@override
Map<String, dynamic> toJson() => {
"id": id,
"furnitureName": furnitureName
};
}
定义后,可以做:
var x = CartItem(
product: Food(
id: '1100112',
foodName: 'Hamburger',
),
)
print(x.toJson());
假设我有这样的数据结构
@JsonSerializable(explicitToJson: true)
class CartItem {
final Product product;
...
}
@JsonSerializable()
class Product {
final String id;
...
}
@JsonSerializable()
class Food extends Product {
final String foodName;
...
}
@JsonSerializable()
class Furniture extends Product {
final String furnitureName;
...
}
我想要的是当我使用 CartItem.toJson()
时它导出到 Json 映射对应于 Product
的类型。
例如
var x = CartItem(
product: Food(
id: '1100112',
foodName: 'Hamburger',
),
)
print(x.toJson());
这应该导致
{
'product': {
'id': '1100112',
'foodName': 'Hamburger',
}
}
同样在使用 fromJson
时,产品的类型为 Food
x.fromJson(x.toJson()) as Food //This should not error
我假设您正在使用包 json_serialization
。对于每个 class,您需要定义以下一些方法:
例如:
factory CartItem.fromJson(Map<String, dynamic> json) => _$CartItemFromJson(json);
Map<String, dynamic> toJson() => _$CartItemToJson(this);
然后你会运行生成命令行:
flutter pub run build_runner build
这将 auto-generate 一个 .g.dart
文件对应于您的
模型文件。
参考:https://pub.dev/packages/json_serializable
否则,如果您希望手动定义方法:
class CartItem {
final Product product;
CartItem({required this.product});
/// fromJson
factory CartItem.fromJson(Map<String, dynamic> json) => CartItem(
product: Product.fromJson(json["product"])
);
/// toJson
Map<String, dynamic> toJson() => {
"product": product.toJson()
};
}
class Product {
final String id;
Product({required this.id});
/// fromJson
factory Product.fromJson(Map<String, dynamic> json) => Product(
id: json["id"]
);
/// toJson
Map<String, dynamic> toJson() => {
"id": id
};
}
class Food extends Product {
final String foodName;
Food({required String id, required this.foodName}) : super(id: id);
/// fromJson
factory Food.fromJson(Map<String, dynamic> json) => Food(
id: json["id"],
foodName: json["foodName"]
);
/// toJson
@override
Map<String, dynamic> toJson() => {
"id": id,
"foodName": foodName
};
}
class Furniture extends Product {
final String furnitureName;
Furniture({required String id, required this.furnitureName}) : super(id: id);
/// fromJson
factory Furniture.fromJson(Map<String, dynamic> json) => Furniture(
id: json["id"],
furnitureName: json["furnitureName"]
);
/// toJson
@override
Map<String, dynamic> toJson() => {
"id": id,
"furnitureName": furnitureName
};
}
定义后,可以做:
var x = CartItem(
product: Food(
id: '1100112',
foodName: 'Hamburger',
),
)
print(x.toJson());