使用嵌套的动态类型解析 JSON
parsing JSON with a nested, dynamic type
假设我有 3 个数据 class(实际上可能更多)。 Class A
或 class B
应包含在 class Wrap
中并带有数据类型标识符.这将允许在应用程序内部对 json 接口提供的任何数据类型使用相同的过程。
class Wrap{
int id;
List<dynamic> dataSet;
Wrap({required this.id, required this.dataSet});
}
class A{
int a=0;
A({this.a});
}
class B{
bool b=true;
B({this.b});
}
我的目标是使用映射 getDataType = {0: A, 1: B};
然后用
解析嵌套的 Json
dataSets: List<dynamic>.from(json["dataSets"].map((d) => getDataType[json["id"].fromJson(d)).toList();
但不幸的是,当尝试从包含类型
的变量访问 class 方法时,这已经失败了
class A{
int i=0; A({i});
factory A.test(int i) => A(2*i);
}
main() {
final t = A;
final x = t.test(2);
}
任何有聪明想法的人如何实现这个?
这种非正统数据结构背后的合理性是:我在业务逻辑层中有一个数据管理器,它根据来自不同逻辑的某些事件触发不同的 UIs。然后管理器获取 UI 的特定数据。为了简化这一点,应使用具有相同功能的相同存储库。但是,存储库功能使用不同的数据库 table,具体取决于 UI.
更新:最基本的例子json:
{
"id": 0,
"data": [
{
"problemId": 0,
"level": 2
}
]
}
首先为数据集
创建一个抽象class
abstract class Dataset {
const Dataset();
factory Dataset.fromMap(Map<String, dynamic> map, int type) {
switch (type) {
case 0:
return ADataset.fromMap(map);
case 1:
return BDataset.fromMap(map);
default:
throw Exception("Class with id $type couldn't be found");
}
}
}
并将 Wrap
class 中的 List<dynamic> dataSet;
替换为 List<Dataset> dataSet;
现在您可以通过扩展 Dataset
class
来简单地创建数据集 classes
class ADataset extends Dataset {
final int fieldA;
ADataset(
this.fieldA,
);
factory ADataset.fromMap(Map<String, dynamic> map) {
return ADataset(map['int field']);
}
}
class BDataset extends Dataset {
final String fieldB;
BDataset(
this.fieldB,
);
factory BDataset.fromMap(Map<String, dynamic> map) {
return BDataset(map['string field']);
}
}
所以现在您需要做的就是
dataSets: List<Dataset>.from(map['datasets'].map(
(dataset) => Dataset.fromMap(dataset, map['type']),
));
假设我有 3 个数据 class(实际上可能更多)。 Class A
或 class B
应包含在 class Wrap
中并带有数据类型标识符.这将允许在应用程序内部对 json 接口提供的任何数据类型使用相同的过程。
class Wrap{
int id;
List<dynamic> dataSet;
Wrap({required this.id, required this.dataSet});
}
class A{
int a=0;
A({this.a});
}
class B{
bool b=true;
B({this.b});
}
我的目标是使用映射 getDataType = {0: A, 1: B};
然后用
dataSets: List<dynamic>.from(json["dataSets"].map((d) => getDataType[json["id"].fromJson(d)).toList();
但不幸的是,当尝试从包含类型
的变量访问 class 方法时,这已经失败了class A{
int i=0; A({i});
factory A.test(int i) => A(2*i);
}
main() {
final t = A;
final x = t.test(2);
}
任何有聪明想法的人如何实现这个?
这种非正统数据结构背后的合理性是:我在业务逻辑层中有一个数据管理器,它根据来自不同逻辑的某些事件触发不同的 UIs。然后管理器获取 UI 的特定数据。为了简化这一点,应使用具有相同功能的相同存储库。但是,存储库功能使用不同的数据库 table,具体取决于 UI.
更新:最基本的例子json:
{
"id": 0,
"data": [
{
"problemId": 0,
"level": 2
}
]
}
首先为数据集
创建一个抽象classabstract class Dataset {
const Dataset();
factory Dataset.fromMap(Map<String, dynamic> map, int type) {
switch (type) {
case 0:
return ADataset.fromMap(map);
case 1:
return BDataset.fromMap(map);
default:
throw Exception("Class with id $type couldn't be found");
}
}
}
并将 Wrap
class 中的 List<dynamic> dataSet;
替换为 List<Dataset> dataSet;
现在您可以通过扩展 Dataset
class
class ADataset extends Dataset {
final int fieldA;
ADataset(
this.fieldA,
);
factory ADataset.fromMap(Map<String, dynamic> map) {
return ADataset(map['int field']);
}
}
class BDataset extends Dataset {
final String fieldB;
BDataset(
this.fieldB,
);
factory BDataset.fromMap(Map<String, dynamic> map) {
return BDataset(map['string field']);
}
}
所以现在您需要做的就是
dataSets: List<Dataset>.from(map['datasets'].map(
(dataset) => Dataset.fromMap(dataset, map['type']),
));