如何用数据库数据加载带国旗的Choice.js下拉选择框
解决Choices.js下拉框绑定带国旗的国家列表问题
你当前代码的核心问题有两个:一是未将Ajax获取的result.paises数据注入到Choices实例中,二是自定义模板里的图片路径绑定错误。下面是修正后的完整方案:
一、修正JavaScript代码
需要在初始化Choices前清空原select选项,再将获取到的国家数据注入,同时修正模板的图片路径绑定:
$.ajax({ url: "/pais-gerenciar/obter-lista-paises-com-imagens", type: "GET", contentType: "application/json", success: function (result) { stopLoader(); if (typeof result.success !== 'undefined' && !result.success) { Swal.fire({ title: 'Ops...', text: result.message, icon: 'error', customClass: { confirmButton: 'btn btn-primary w-xs' }, buttonsStyling: false, allowOutsideClick: false }); return false; } let selPais = $(genericModalOrBodyInstance).find('.enderecamento-postal-sel-pais')[0]; // 清空原select的默认选项 $(selPais).empty(); // 初始化Choices实例 const choicesInstance = new Choices(selPais, { allowHTML: true, placeholder: true, renderChoiceLimit: -1, position: 'auto', resetScrollPosition: true, searchEnabled: true, loadingText: 'Carregando...', noResultsText: 'Nenhum resultado encontrado', noChoicesText: 'Sem opções para escolher', itemSelectText: 'Clique para selecionar', callbackOnCreateTemplates: function (template) { const classNames = this.config.classNames; const itemSelectText = this.config.itemSelectText; return { choice: function(classNames, data) { // 处理虚拟路径~/,转换为根路径 const imageSrc = data.imageUrl.replace('~/', '/'); return template(`<div class="${String(classNames.item)} ${String(classNames.itemChoice)} ${String(data.disabled ? classNames.itemDisabled : classNames.itemSelectable)}" data-select-text="${String(itemSelectText)}" data-choice ${String(data.disabled ? 'data-choice-disabled aria-disabled=true' : 'data-choice-selectable')} data-id="${String(data.id)}" data-value="${String(data.value)}" data-label="${String(data.label)}" ${String(data.groupId > 0 ? 'role="treeitem"' : 'role="option"')}> <img src="${imageSrc}" alt="${data.label}" style="width:24px; margin-right:8px;"> ${String(data.label)} </div>`); }, // 可选:自定义已选中项的显示模板,保持国旗展示 item: function(classNames, data) { const imageSrc = data.imageUrl.replace('~/', '/'); return template(`<div class="${String(classNames.item)} ${String(classNames.itemChoice)} ${String(data.disabled ? classNames.itemDisabled : classNames.itemSelectable)}" data-select-text="${String(itemSelectText)}" data-choice ${String(data.disabled ? 'data-choice-disabled aria-disabled=true' : 'data-choice-selectable')} data-id="${String(data.id)}" data-value="${String(data.value)}" data-label="${String(data.label)}"> <img src="${imageSrc}" alt="${data.label}" style="width:20px; margin-right:6px;"> ${String(data.label)} </div>`); } }; } }); // 将Ajax获取的国家数据注入Choices choicesInstance.setChoices( result.paises.map(pais => ({ id: pais.Id, value: pais.Value, label: pais.Label, imageUrl: pais.imageUrl })), 'value', 'label', false ); return true; }, error: function (e) { stopLoader(); redirectToError(e.status); return false; } });
二、关键修正点说明
- 数据注入:通过
choicesInstance.setChoices()方法将result.paises映射后的数据传入Choices,确保下拉选项能获取到imageUrl等自定义属性。 - 路径处理:将后端返回的虚拟路径
~/替换为根路径/,保证浏览器能正确加载图片资源。 - 模板修正:把原模板中错误的
${String(data)}改为处理后的图片路径imageSrc,同时为图片添加alt属性和基础样式,优化视觉体验。 - 清空默认选项:初始化前清空select的原有选项,避免出现重复数据。
三、可选优化:后端直接返回绝对路径
如果不想在前端处理路径,可以在后端Action中直接生成完整绝对路径:
[HttpGet] [Authorize] [Route("pais-gerenciar/obter-lista-paises-com-imagens")] public JsonResult GetPaisesComImagens() { var hostUrl = $"{Request.Scheme}://{Request.Host}"; var paises = _paisAppService.GetAllBy(null, null).Select(x => new ImageOptionViewModel { Id = x.Id.ToString(), Label = x.NomePtBr, Value = x.Id.ToString(), // 直接返回完整绝对路径 imageUrl = x.ImagemBandeiraURL.Replace("~/", $"{hostUrl}/") }); return Json(new { success = true, paises }); }
此时前端无需再处理路径,直接使用data.imageUrl即可。
内容的提问来源于stack exchange,提问作者masterj
相关产品推荐
相关产品推荐

