应该只有一项具有 [DropdownButton] 的值:“合作伙伴”的实例
Posted
技术标签:
【中文标题】应该只有一项具有 [DropdownButton] 的值:“合作伙伴”的实例【英文标题】:There should be exactly one item with [DropdownButton]'s value: Instance of 'Partner' 【发布时间】:2021-11-05 20:11:04 【问题描述】:我的下拉菜单按预期工作。但是当我选择一个项目时,我的应用程序因错误而崩溃
There should be exactly one item with [DropdownButton]'s value: Instance of 'Partner'.
Either zero or 2 or more [DropdownMenuItem]s were detected with the same value
首先我在类中声明我的变量
class _MultipleTestBookingState extends State<MultipleTestBooking>
Partner? _selectedLab;
Datum? _selectedTest;
....................
使用Partner?_selectedLab;
声明,因为我的下拉菜单包含合作伙伴列表
然后使用这个变量在我的下拉列表中显示选定的值
Container(
child: FutureBuilder<List<Partner>>(
future: AllPathLab(),
builder:
(BuildContext context, AsyncSnapshot snapshot)
if (snapshot.connectionState !=ConnectionState.done)
return CircularProgressIndicator();
if (snapshot.hasError)
return Text("Somthing went wrong");
if (snapshot.hasData)
return DropdownButton<Partner>(
value: _selectedLab,
hint: Text("Select Lab"),
items: snapshot.data.map((Partner data) =>
DropdownMenuItem<Partner>(
child: Text("$data.partnerName"),
value: data,
)
).toList().cast<DropdownMenuItem<Partner>>(),
onChanged: (value)
setState(()
_selectedLab=value;
encLabId = value!.encPartnerId;
GetTestByLab();
);
);
return Text("Waiting for Internet Connection");
,
),
),
Full code with my JSON response
【问题讨论】:
请检查您是否以正确的方式获取数据。如果可能,您可以添加 AllPathLab() 和 api 正在获取的示例 json 格式。 我相信我正在正确获取我的数据,因为单击下拉菜单会显示我来自 API 的所有数据。当我在 setState 中更改_selectedLab
时出现错误。
我放了 My API fucntion 和我的 JSON response 的链接。你现在可以检查一下吗[gist.github.com/Roy-Tuhin/85dae5e908b21c92cb19a7f3c82dc0e7]
是的,我正在检查它,因为您有两个 api 点击您只提供了一个 json 示例,请同时提供并告诉我
哦!我的依赖下拉列表的第二个 api.. 我添加了名为 Get Test by Lab response
[ gist.github.com/Roy-Tuhin/85dae5e908b21c92cb19a7f3c82dc0e7 ] 的 json 响应文件
【参考方案1】:
因此,根据您提供的数据,我创建了以下代码:
import 'package:date_time_picker/date_time_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/Patner.dart';
import 'package:flutter_app/dataModel.dart';
import 'package:http/http.dart' as http;
void main()
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
home: MyApp(),
));
class MyApp extends StatefulWidget
const MyApp(Key key) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
class _MyAppState extends State<MyApp>
Partner _selectedLab;
Datum _selectedTest;
Future getAllPathLabResults;
Future getTestByLabResult;
String encLabId = '';
void initState()
super.initState();
getAllPathLabResults = allPathLab();
getTestByLabResult = getTestByLab();
String _selectedDate = DateTime.now().toString();
Future<List<Partner>> allPathLab() async
String jsonData = jsonstring;
final model = modelFromJson(jsonData);
print("This is the list length : $model.partner.length");
List<Partner> arrData = model.partner;
// this Future is for sample as you will be fetching the api data remove this one
Future.delayed(Duration(seconds: 3));
return arrData;
Future<List<Datum>> getTestByLab() async
print("This is the Id :$encLabId");
_selectedTest = null;
var response = await http.post(
Uri.parse("http://medbo.digitalicon.in/api/medboapi/GetTestByLab"),
body: ("EncId": encLabId));
if (response.statusCode == 200)
final dataModel = dataModelFromJson(response.body);
print(dataModel.data.length);
for (final item in dataModel.data)
print("This is hte test name :$item.testName");
List<Datum> arrData = dataModel.data;
return arrData;
return [];
@override
Widget build(BuildContext context)
var screenWidth = MediaQuery.of(context).size.width;
var screenHeight = MediaQuery.of(context).size.height;
var blockSizeHorizontal = (screenWidth / 100);
var blockSizeVertical = (screenHeight / 100);
return Scaffold(
body: SafeArea(
child: Container(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: ListTile(
title: Text("Booking Information",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: blockSizeHorizontal * 5,
fontFamily: 'Poppins',
color: Theme.of(context).primaryColor,
)),
subtitle: Text("Preferred Visit Date"),
),
),
Container(
margin: EdgeInsets.only(left: 20),
padding: EdgeInsets.only(left: 0, right: 150),
decoration: BoxDecoration(
color: Colors.lightBlue[50],
borderRadius: BorderRadius.all(Radius.circular(12)),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: DateTimePicker(
initialValue: DateTime.now().toString(),
//initialValue:'', // initialValue or controller.text can be null, empty or a DateTime string otherwise it will throw an error.
type: DateTimePickerType.date,
dateLabelText: 'Select Date',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: blockSizeHorizontal * 3.5,
fontFamily: 'Poppins',
color: Colors.green,
letterSpacing: 2.0,
),
firstDate: DateTime.now(),
lastDate: DateTime.now().add(Duration(days: 30)),
// This will add one year from current date
validator: (value)
return null;
,
onChanged: (value)
if (value.isNotEmpty)
setState(()
_selectedDate = value;
);
,
onSaved: (value)
if (value.isNotEmpty)
_selectedDate = value;
,
),
),
),
ListTile(
title: Text(
"Select Pathological Lab",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: blockSizeHorizontal * 4.0,
fontFamily: 'Poppins',
color: Theme.of(context).primaryColor,
),
),
),
Container(
child: FutureBuilder<List<Partner>>(
future: getAllPathLabResults,
builder: (BuildContext context, AsyncSnapshot snapshot)
if (snapshot.connectionState != ConnectionState.done)
return CircularProgressIndicator();
if (snapshot.hasError)
return Text("Somthing went wrong");
if (snapshot.hasData)
List<Partner> data =
snapshot.hasData ? snapshot.data : [];
return DropdownButton<Partner>(
value: _selectedLab,
hint: Text("Select Lab"),
//underline: SizedBox(),
//isExpanded: true,
items: data
.map((Partner data) => DropdownMenuItem<Partner>(
child: Text("$data.partnerName"),
value: data,
))
.toList()
.cast<DropdownMenuItem<Partner>>(),
onChanged: (value)
setState(()
_selectedLab = value;
encLabId = value.encPartnerId;
getTestByLabResult = getTestByLab();
);
//GetTestByLab(value!.encPartnerId); // passing encid to my next API function
// GetTestByLab();
,
);
return Text("Waiting for Internet Connection");
,
),
),
//=========================================================== Dependent drop down===================================
ListTile(
title: Text(
"Test Name",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: blockSizeHorizontal * 4.0,
fontFamily: 'Poppins',
color: Theme.of(context).primaryColor,
),
),
),
Container(
child: FutureBuilder<List<Datum>>(
future: getTestByLabResult,
builder: (BuildContext context, AsyncSnapshot snapshot)
if (snapshot.connectionState != ConnectionState.done)
return CircularProgressIndicator();
if (snapshot.hasError)
return Text("Select a Lab for your Test");
if (snapshot.hasData)
List<Datum> data = snapshot.hasData ? snapshot.data : [];
return DropdownButton<Datum>(
value: _selectedTest,
hint: Text(""),
//underline: SizedBox(),
//isExpanded: true,
items: data
.map((Datum data) => DropdownMenuItem<Datum>(
child: Text("$data.testName"),
value: data,
))
.toList()
.cast<DropdownMenuItem<Datum>>(),
onChanged: (value)
print("This is the value : $value.testName");
setState(()
_selectedTest = value;
);
//GetTestByLab(value!.encPartnerId); // passing encid to my next API function
);
return Text("Waiting for Internet Connection");
,
),
),
],
),
),
),
);
// used this as a sample
String jsonstring = '''
"Status": "1",
"Message": "",
"Partner": [
"EncPartnerId": "IujyQXg8KZg8asLvK/FS7g==",
"PartnerName": "dasfdsf"
,
"EncPartnerId": "pEl2B9kuumKRxIxLJO76eQ==",
"PartnerName": "partner172"
,
"EncPartnerId": "eYwtNBXR6P/JDtsIwr+Bvw==",
"PartnerName": "nnkb"
,
"EncPartnerId": "kFgorcFF0G6RQD4W+LwWnQ==",
"PartnerName": "nnkjj"
,
"EncPartnerId": "U4exk+vfMGrn7cjNUa/PBw==",
"PartnerName": "mahadev"
,
"EncPartnerId": "tqkaSjTFgDf0612mp9mbsQ==",
"PartnerName": null
,
"EncPartnerId": "0aruO0FbYOu5IerRBxdT8w==",
"PartnerName": "Suraksha Diagnostics"
,
"EncPartnerId": "65gtodyhbtdInTsJWr1ZkA==",
"PartnerName": "Rasomoy pvt. Hospital"
,
"EncPartnerId": "LEuT1eIlpLEMAAkZme3wpQ==",
"PartnerName": "Tangra medical House"
,
"EncPartnerId": "q8O8YMzYKXSB4RtkX4k7Lw==",
"PartnerName": "Partner new"
]
''';
API 模型:
// To parse this JSON data, do
//
// final model = modelFromJson(jsonString);
import 'dart:convert';
Model modelFromJson(String str) => Model.fromJson(json.decode(str));
String modelToJson(Model data) => json.encode(data.toJson());
class Model
Model(
this.status,
this.message,
this.partner,
);
String status;
String message;
List<Partner> partner;
factory Model.fromJson(Map<String, dynamic> json) => Model(
status: json["Status"],
message: json["Message"],
partner:
List<Partner>.from(json["Partner"].map((x) => Partner.fromJson(x))),
);
Map<String, dynamic> toJson() =>
"Status": status,
"Message": message,
"Partner": List<dynamic>.from(partner.map((x) => x.toJson())),
;
class Partner
Partner(
this.encPartnerId,
this.partnerName,
);
String encPartnerId;
String partnerName;
factory Partner.fromJson(Map<String, dynamic> json) => Partner(
encPartnerId: json["EncPartnerId"],
partnerName: json["PartnerName"] == null ? null : json["PartnerName"],
);
Map<String, dynamic> toJson() =>
"EncPartnerId": encPartnerId,
"PartnerName": partnerName == null ? null : partnerName,
;
第二个api解析模型
// To parse this JSON data, do
//
// final dataModel = dataModelFromJson(jsonString);
import 'dart:convert';
DataModel dataModelFromJson(String str) => DataModel.fromJson(json.decode(str));
String dataModelToJson(DataModel data) => json.encode(data.toJson());
class DataModel
DataModel(
this.status,
this.message,
this.data,
);
String status;
String message;
List<Datum> data;
factory DataModel.fromJson(Map<String, dynamic> json) => DataModel(
status: json["Status"],
message: json["Message"],
data: json["Data"] == null
? []
: List<Datum>.from(json["Data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() =>
"Status": status,
"Message": message,
"Data":
data == null ? [] : List<dynamic>.from(data.map((x) => x.toJson())),
;
class Datum
Datum(
this.testId,
this.encTestId,
this.testName,
this.noOfPartner,
this.testFee,
this.discountedFee,
this.bookingFee,
this.reportTime,
this.note,
this.createBy,
this.createDate,
this.modBy,
this.modDate,
this.activeStatus,
this.permission,
);
String testId;
dynamic encTestId;
String testName;
dynamic noOfPartner;
dynamic testFee;
dynamic discountedFee;
dynamic bookingFee;
dynamic reportTime;
dynamic note;
dynamic createBy;
dynamic createDate;
dynamic modBy;
dynamic modDate;
dynamic activeStatus;
dynamic permission;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
testId: json["TestId"],
encTestId: json["EncTestId"],
testName: json["TestName"],
noOfPartner: json["NoOfPartner"],
testFee: json["TestFee"],
discountedFee: json["DiscountedFee"],
bookingFee: json["BookingFee"],
reportTime: json["ReportTime"],
note: json["Note"],
createBy: json["CreateBy"],
createDate: json["CreateDate"],
modBy: json["ModBy"],
modDate: json["ModDate"],
activeStatus: json["ActiveStatus"],
permission: json["Permission"],
);
Map<String, dynamic> toJson() =>
"TestId": testId,
"EncTestId": encTestId,
"TestName": testName,
"NoOfPartner": noOfPartner,
"TestFee": testFee,
"DiscountedFee": discountedFee,
"BookingFee": bookingFee,
"ReportTime": reportTime,
"Note": note,
"CreateBy": createBy,
"CreateDate": createDate,
"ModBy": modBy,
"ModDate": modDate,
"ActiveStatus": activeStatus,
"Permission": permission,
;
因此,当您最初根据 id 获取数据并选择第二个下拉菜单时。现在,当您更改实验室时,您可以将所选文本设为空。 而且您还以错误的方式使用了futurebuilder方法,因为调用了setstate它正在创建多个rebuids并给出错误。
请运行代码并检查其是否正常工作。
【讨论】:
好的,正在尝试!快速提问:我可以从 Api 获取我的Lab
数据吗? Future<List<Partner>> allPathLab() async String jsonData = jsonstring;
当我们通过 api 调用获取 Test
的数据时
目前上面的代码是用来从字符串中获取你提供的json,使用你提供的gist中的代码,它不会改变。
进行 api 调用检查 200 成功,然后从 response.body 获取数据,将其添加到最后一个模型 = modelFromJson(response.body);以上是关于应该只有一项具有 [DropdownButton] 的值:“合作伙伴”的实例的主要内容,如果未能解决你的问题,请参考以下文章
Flutter GetBuilder Dependent DropDownButton - 即使值已被重置,也应该只有一项具有 [DropdownButton] 的值
Flutter DropdownButton 颜色与父 Widgets 相同