从 Dart 中的 json 文件中获取嵌套列表内容,但返回“'FormContent'的实例”
Posted
技术标签:
【中文标题】从 Dart 中的 json 文件中获取嵌套列表内容,但返回“\'FormContent\'的实例”【英文标题】:Get nested list content from json file in Dart, but returning "Instance of 'FormContent' "从 Dart 中的 json 文件中获取嵌套列表内容,但返回“'FormContent'的实例” 【发布时间】:2022-01-21 03:56:19 【问题描述】:我有一个 JSON 格式的列表,如下所示。我需要将这些列表转换为 Flutter 中的 DropDownMenu 项。为此,
-
从 JSON 文件中读取数据
将数据转换为可用的类格式(FormContent 类)
创建一个返回 FormContent 列表的 Future。
读取 FutureBuilder 中的数据
将 FormContent 列表转换为 DropDownMenu 可以接受的字符串列表
在我打印items
的第一项的最后,我得到Instance of 'FormContent'
作为这次执行的结果(我在下面的FutureBuilder 小部件中标记了它)。我期待的是 JSON 文件中的"stajTuru"
列表。
["Ortopedi", "Kardiyoloji","Dermatoloji", "Pediatri"]
由于存在嵌套列表格式。我尝试执行print(items[0][0].toString());
来获取第一项的内容。但是,我收到这样的错误
Class 'FormContent' has no instance method '[]'.Receiver: Instance of 'FormContent' Tried calling: [](0)
综上所述,我需要将这些 JSON 内容转换为单独的 List<String>
。就像我在上面所期待的那样。
JSON 文件
[
"stajTuru": [ "Ortopedi", "Kardiyoloji","Dermatoloji", "Pediatri"],
"cinsiyet": ["Erkek","Kadın", "Diğer"],
"etkilesimTuru": [ "Gözlem", "Yardımla yapma","Yardımsız yapma","Sanal olgu"],
"kapsam": [ "Öykü", "Fizik Bakı", "Tanısal akıl Yürütme", "Teropötik akıl yürütme"],
"ortam": ["Poliklinik","Servis","Acil","Ameliyathane","Dış Kurum"],
"doktor": [ "Esra Demir","Mehmet Uçar","Kemal Yurdakul","Fehmi Öztürk","Mehmet Öz"]
]
FormContent 类
这是我保留每个列表的班级
class FormContent
late List<dynamic> _cinsiyetItems;
late List<dynamic> _stajTuruItems;
late List<dynamic> _etkilesimTuruItems;
late List<dynamic> _kapsamItems;
late List<dynamic> _ortamItems;
late List<dynamic> _doktorItems;
FormContent.fromJson(Map<String,dynamic> jsonFile)
_cinsiyetItems=jsonFile['cinsiyet']!.toList();
_stajTuruItems=jsonFile['stajTuru']!.toList();
_etkilesimTuruItems=jsonFile['etkilesimTuru']!.toList();
_kapsamItems=jsonFile['kapsam']!.toList();
_ortamItems=jsonFile['ortam']!.toList();
_doktorItems=jsonFile['doktor']!.toList();
读取JSON的方法
这是我将 JSON 数据转换为列表的方法
Future<List<dynamic>> readJsonData() async
final jsonData = await rootBundle.rootBundle.loadString('assets/json/formdata.json');
print(jsonData.toString());
final list = json.decode(jsonData) as List<dynamic>;
print("======================================");
print(list.toString());
var result =list.map((e) => FormContent.fromJson(e)).toList();
print("------------------------------------------");
print(result.toString());
return result;
FutureBuilder 方法
最后,这是我的 FutureBuilder 来执行数据
FutureBuilder(
future:readJsonData() ,
builder: (context,snapshot)
if(snapshot.hasError)
return Text(snapshot.error.toString());
else if(snapshot.hasData)
var items =snapshot.data as List<dynamic>;
print("--------------***********************************");
print(items[0].toString()); // <--- HERE
return
ListView(
children: [
myTextFieldRow("Kayıt No: ", 10,_formData.setKayitNo),
myDropDownContainer(_valueStajTuru,_stajTuruItems,
hintTextStajTuru, onChangedStajTuru),
// myDropDownContainer(_valueDoktor, _doktorItems, hintTextDoktor, onChangedDoktor),
myTextFieldRow("Hastanın Yaşı:", 3, _formData.setYas),
// myDropDownContainer(_valueCinsiyet, _cinsiyetItems, hintTextCinsiyet, onChangedCinsiyet),
myTextFieldRow("Şikayet:", 10,_formData.setSikayet),
myTextFieldRow("Ayırıcı Tanı:", 50,_formData.setAyiriciTani),
myTextFieldRow("Kesin Tanı:", 50,_formData.setKesinTani),
myTextFieldRow("Tedavi Yöntemi:", 100,_formData.setTedaviYontemi),
// myDropDownContainer(_valueEtkilesim, _etkilesimTuruItems, hintTextEtkilesim, onChangedEtkilesim),
// myDropDownContainer(_valueKapsam, _kapsamItems, hintTextKapsam, onChangedKapsam),
// myDropDownContainer(_valueOrtam, _ortamItems, hintTextOrtam, onChangedOrtam),
const SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
SizedBox(
width: 150,
height: 50,
child: TextButton(
onPressed: ()
setState(()
_formAdd.addNewFormToList(_formData);
_formData=FormData();
Navigator.push(context, MaterialPageRoute(builder: (context)=> StudentProfile(formAdd: _formAdd)));
);
,
child: Text(
"GÖNDER",
style: kTextStyle.copyWith(fontSize: 20),
),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(
const Color(0xff4F4DBB),
),
),
),
),
],
),
],
);
else
return const Center(child:CircularProgressIndicator(),);
)),
【问题讨论】:
【参考方案1】:首先,您的FormContent
类需要以某种方式进行修改。类中的所有内容当前都是私有的,因此您无法获取类中包含的数据。您也可以通过指定列表类型List<String>
而不是List<dynamic>
来更具体,并且也不需要设置属性late
。这是我建议的课程重写:
class FormContent
List<String> cinsiyetItems;
List<String> stajTuruItems;
List<String> etkilesimTuruItems;
List<String> kapsamItems;
List<String> ortamItems;
List<String> doktorItems;
FormContent.fromJson(Map<String, dynamic> jsonFile)
: cinsiyetItems = [...?jsonFile['cinsiyet']],
stajTuruItems = [...?jsonFile['stajTuru']],
etkilesimTuruItems = [...?jsonFile['etkilesimTuru']],
kapsamItems = [...?jsonFile['kapsam']],
ortamItems = [...?jsonFile['ortam']],
doktorItems = [...?jsonFile['doktor']];
至于您的readJsonData
函数,您应该通过将类型指定为Future<List<FormContent>>
而不是Future<List<dynamic>>
来更具体。我会改写如下:
Future<List<FormContent>> readJsonData() async
final jsonData = await rootBundle.rootBundle.loadString('assets/json/formdata.json');
return [
for (final e in json.decode(jsonData)) FormContent.fromJson(e),
];
关于这个问题:
在我打印项目的第一项的最后,我得到了“FormContent”的实例作为这个执行的结果(我在下面的 FutureBuilder 小部件中标记了它)。我期待的是 JSON 文件中的“stajTuru”列表。
您只是打印出您从readJsonData
获得的第一个元素,它是您的FormContent
类的一个实例。您可以通过print(items[0].stajTuruItems);
来查看打印出来的stajTuru
列表。
【讨论】:
【参考方案2】:你搞错了,表单内容属性需要公开,
print(items[0][0].toString());
此调用首先调用,item[0]
不是一个列表,它是一个对象,它具有 _cinsiyetItems、_stajTuruItems 等属性。
items[0]
是表单内容的一个实例,您需要访问第一个元素,您需要访问表单内容的属性,例如
items[0]. _cinsiyetItems
在这里你会发现列表字符串包含和你需要调用的第一个字符串
items[0]. _cinsiyetItems[0] // Erkek
查看link
【讨论】:
【参考方案3】:所以你有一个列表列表,并将其变成一个包含一堆列表的类,但是你忘记实现一种访问所述列表中信息的方法。
如果你想获取列表,你可以这样做:
class FormContent
late List<dynamic> _cinsiyetItems;
late List<dynamic> _stajTuruItems;
late List<dynamic> _etkilesimTuruItems;
late List<dynamic> _kapsamItems;
late List<dynamic> _ortamItems;
late List<dynamic> _doktorItems;
List<dynamic> get firstList => _cinsiyetItems;
List<dynamic> get secondList => _stajTuruItems;
List<dynamic> get thirdList => _etkilesimTuruItems;
List<dynamic> get fourthList => _kapsamItems;
List<dynamic> get fifthList => _ortamItems;
List<dynamic> get sixthList => _doktorItems;
FormContent.fromJson(Map<String,dynamic> jsonFile)
_cinsiyetItems=jsonFile['cinsiyet']!.toList();
_stajTuruItems=jsonFile['stajTuru']!.toList();
_etkilesimTuruItems=jsonFile['etkilesimTuru']!.toList();
_kapsamItems=jsonFile['kapsam']!.toList();
_ortamItems=jsonFile['ortam']!.toList();
_doktorItems=jsonFile['doktor']!.toList();
这样您就可以通过items[0].firstList
访问您想要的值
你也可以像这样创建一个列表 getter:
class FormContent
late List<dynamic> _cinsiyetItems;
late List<dynamic> _stajTuruItems;
late List<dynamic> _etkilesimTuruItems;
late List<dynamic> _kapsamItems;
late List<dynamic> _ortamItems;
late List<dynamic> _doktorItems;
List<List<dynamic>> get values => [
_cinsiyetItems,
_stajTuruItems,
_etkilesimTuruItems,
_kapsamItems,
_ortamItems,
_doktorItems,
];
FormContent.fromJson(Map<String,dynamic> jsonFile)
_cinsiyetItems=jsonFile['cinsiyet']!.toList();
_stajTuruItems=jsonFile['stajTuru']!.toList();
_etkilesimTuruItems=jsonFile['etkilesimTuru']!.toList();
_kapsamItems=jsonFile['kapsam']!.toList();
_ortamItems=jsonFile['ortam']!.toList();
_doktorItems=jsonFile['doktor']!.toList();
这样你就可以像这样访问值:items[0].values[0]
最后,要在打印 items 变量时打印值,您需要重写 toString 方法:
class FormContent
late List<dynamic> _cinsiyetItems;
late List<dynamic> _stajTuruItems;
late List<dynamic> _etkilesimTuruItems;
late List<dynamic> _kapsamItems;
late List<dynamic> _ortamItems;
late List<dynamic> _doktorItems;
List<List<dynamic>> get values => [
_cinsiyetItems,
_stajTuruItems,
_etkilesimTuruItems,
_kapsamItems,
_ortamItems,
_doktorItems,
];
FormContent.fromJson(Map<String,dynamic> jsonFile)
_cinsiyetItems=jsonFile['cinsiyet']!.toList();
_stajTuruItems=jsonFile['stajTuru']!.toList();
_etkilesimTuruItems=jsonFile['etkilesimTuru']!.toList();
_kapsamItems=jsonFile['kapsam']!.toList();
_ortamItems=jsonFile['ortam']!.toList();
_doktorItems=jsonFile['doktor']!.toList();
@override
String toString()
return '[$_cinsiyetItems, $_stajTuruItems, $_etkilesimTuruItems, $_kapsamItems, $_ortamItems, $doktorItems]';
【讨论】:
以上是关于从 Dart 中的 json 文件中获取嵌套列表内容,但返回“'FormContent'的实例”的主要内容,如果未能解决你的问题,请参考以下文章