如何基于首个Select2选择,通过AJAX结合OptGroup填充第二个Select2?
解决Select2按行程分组动态填充套餐的问题
1. 后端应返回的JSON格式
后端需要返回按行程分组的数据结构,每个行程对象包含行程名称(作为分组标题)和对应的套餐列表。示例格式如下:
[ { "TripId": "123", "TripName": "Trip Name 1", "Packages": [ {"id": "pkg1", "PackageName": "Package A"}, {"id": "pkg2", "PackageName": "Package B"} ] }, { "TripId": "456", "TripName": "Trip Name 2", "Packages": [ {"id": "pkg3", "PackageName": "Package C"}, {"id": "pkg4", "PackageName": "Package D"} ] } ]
- 每个外层对象对应一个行程分组
TripName作为分组的显示标题Packages数组是该行程下的所有套餐,每个套餐需包含唯一标识id和显示名称PackageName(字段名可自定义,前端对应处理即可)
2. processResults数据处理及完整代码
Select2识别分组的规则是:每个分组对象必须包含text(分组标题)和children(分组内的选项数组),每个选项需包含id和text字段。修改updatePackages函数如下:
function updatePackages(){ // 先销毁已有Select2实例,避免重复初始化导致的异常 $("#SelectPackages").select2('destroy').select2({ ajax: { url: "/data/trip-packages-lists?ids=" + $("#EmailSentToGroup").val(), type: "POST", dataType: "json", // 注意去掉原代码中多余的单引号 processResults: function (data) { // 将后端返回的分组数据转换为Select2可识别的格式 const groupedResults = data.map(trip => ({ text: trip.TripName, // 映射为分组标题 children: trip.Packages.map(pkg => ({ id: pkg.id, text: pkg.PackageName // 映射为套餐显示名称 })) })); return { results: groupedResults }; } }, placeholder: "Select Package(s)...", // 可选:添加占位提示 allowClear: true // 可选:允许清空选择 }); }
关键说明:
- 每次初始化前调用
select2('destroy'),避免重复绑定事件或渲染异常 - 通过两层
map转换数据:外层遍历行程生成分组,内层遍历套餐生成分组内的选项 - 字段映射需和后端返回的JSON字段严格对应,比如后端套餐名称用
Name而非PackageName,则修改为pkg.Name
内容的提问来源于stack exchange,提问作者Dennis
相关产品推荐
相关产品推荐

