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

如何用数据库数据加载带国旗的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 11:55:40