You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 16:02:04