Flutter带搜索的多选下拉框API填充问题求助
Flutter带搜索多选下拉框API数据填充问题解决
问题描述
开发Flutter应用时需要实现带搜索功能的多选下拉框组件。最初选用select2dot1: ~2.0.9包,它支持多选和动态搜索,但与GetBuilder配合时无法正常工作。改用bs_flutter_selectbox: ^1.3.0组件后功能需求可满足,但使用其serverSide属性从API填充数据时遇到模型映射问题,请求解决数据填充问题。
现有代码示例
视图代码
Container( margin: const EdgeInsets.only(bottom: 10.0), child: BsSelectBox( searchable: true, // serverSide: controller.selectApi, controller: controller.select6, autoClose: false, alwaysUpdate: false, padding: const EdgeInsets.fromLTRB( 20.0, 12.0, 20.0, 12.0), hintTextLabel: 'Pilih salah satu', style: BsSelectBoxStyle( backgroundColor: Color.fromARGB(255, 255, 255, 255), hintTextColor: Color.fromARGB(255, 0, 0, 0), selectedColor: Color.fromARGB(255, 247, 247, 247), selectedTextColor: Colors.white, textColor: Colors.white, focusedTextColor: Color.fromARGB(255, 255, 255, 255), borderRadius: BorderRadius.circular(50.0), ), dialogStyle: BsDialogBoxStyle( borderRadius: BorderRadius.circular(20.0), ), paddingDialog: const EdgeInsets.all(15), marginDialog: const EdgeInsets.only(top: 5.0, bottom: 5.0), ), ),
控制器代码
BsSelectBoxController select6 = BsSelectBoxController(multiple: true, options: [ const BsSelectBoxOption(value: 1, text: Text('1')), const BsSelectBoxOption(value: 2, text: Text('2')), const BsSelectBoxOption(value: 3, text: Text('3')), const BsSelectBoxOption(value: 4, text: Text('4')), const BsSelectBoxOption(value: 5, text: Text('5')), const BsSelectBoxOption(value: 6, text: Text('6')), ]); Future<BsSelectBoxResponse> selectApi(Map<String, String> params) async { String apipage = "match/fetch/fetchZipcode.php"; Map mappedData = {}; var response = await sendDataServer(apipage, mappedData); var servResJson = response.data; var data = json.decode(servResJson)["data"]; var arrayDB = Zipcode.fromJson({"zipcode": data}); zipCodes = arrayDB.zipcode; return BsSelectBoxResponse.createFromJson(zipCodes); }
API响应格式
{ "zipcode": [ { "zipcode_id": 1, "manage_country_id": 1, "state_id": 53, "zipcode": "T4A" }, { "zipcode_id": 2, "manage_country_id": 1, "state_id": 53, "zipcode": "T4B" }, //...更多数据 ] }
解决方案
问题核心是BsSelectBoxResponse.createFromJson要求输入的JSON结构匹配组件默认的value和text字段,但API返回的是zipcode_id和zipcode字段,无法直接映射。以下是修正步骤:
1. 修正API数据转换逻辑
手动将API返回的zipcode列表转换为BsSelectBoxOption数组,再生成BsSelectBoxResponse:
Future<BsSelectBoxResponse> selectApi(Map<String, String> params) async { String apipage = "match/fetch/fetchZipcode.php"; Map mappedData = {}; var response = await sendDataServer(apipage, mappedData); var servResJson = response.data; // 注意API响应根字段是"zipcode",不是"data" var zipcodeList = json.decode(servResJson)["zipcode"]; // 转换为组件所需的BsSelectBoxOption列表 List<BsSelectBoxOption> options = zipcodeList.map((item) { return BsSelectBoxOption( value: item["zipcode_id"], // 用zipcode_id作为选项值 text: Text(item["zipcode"]), // 用zipcode作为显示文本 ); }).toList(); // 返回符合要求的响应对象 return BsSelectBoxResponse(options: options, total: options.length); }
2. 调整控制器与视图配置
- 控制器中初始化空的
BsSelectBoxController(serverSide会动态加载数据):
BsSelectBoxController select6 = BsSelectBoxController(multiple: true);
- 视图中启用
serverSide属性:
BsSelectBox( searchable: true, serverSide: controller.selectApi, // 取消注释 controller: controller.select6, // ...其他配置 )
3. 可选:修正模型类(若需保留)
如果仍需使用Zipcode模型,确保其解析逻辑正确:
class Zipcode { final List<ZipcodeItem> zipcode; Zipcode({required this.zipcode}); factory Zipcode.fromJson(Map<String, dynamic> json) { return Zipcode( zipcode: List<ZipcodeItem>.from( json["zipcode"].map((x) => ZipcodeItem.fromJson(x)), ), ); } } class ZipcodeItem { final int zipcodeId; final int manageCountryId; final int stateId; final String zipcode; ZipcodeItem({ required this.zipcodeId, required this.manageCountryId, required this.stateId, required this.zipcode, }); factory ZipcodeItem.fromJson(Map<String, dynamic> json) { return ZipcodeItem( zipcodeId: json["zipcode_id"], manageCountryId: json["manage_country_id"], stateId: json["state_id"], zipcode: json["zipcode"], ); } }
内容的提问来源于stack exchange,提问作者sayantan poddar
相关产品推荐
相关产品推荐

