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

Blazor Server自定义Select2多选控件选中值显示Null问题排查

Blazor Server中Select2多选控件无法获取选中值的问题解决

问题原因分析

  1. Select2覆盖原生控件事件:Select2会替换原生<select>元素生成自定义DOM,用户的选择操作不会触发原生的@onchange事件,导致你定义的OnSelectionChanged方法从未执行。
  2. 类型不匹配:你的serverID是int类型,但SelectedValues是List<string>,初始值设置时类型不兼容,叠加事件未触发的问题,最终选中值始终为Null。
  3. 未建立JS与Blazor的正确联动:没有监听Select2自身的change事件来通知Blazor更新状态。

解决方案

1. 修改JS互操作代码(Select2JsInterop.js)

新增Select2的change事件监听,通过DotNet对象引用通知Blazor组件更新:

window.select2Interop = {
    initializeSelect2: function (elementId, dotNetRef) {
        $('#' + elementId).select2({
            width: '100%',
            multiple: true
        }).on('change', function() {
            const selectedValues = $(this).val();
            dotNetRef.invokeMethodAsync('OnSelect2SelectionChanged', selectedValues);
        });
    },

    getSelectedValues: function (elementId) {
        return $('#' + elementId).val();
    },

    setSelectedValues: function (elementId, values) {
        $('#' + elementId).val(values).trigger('change');
    }
};

2. 重构自定义Select2组件(Select2MultiSelect.razor)

移除原生@onchange,改用JS触发的回调,同时处理类型转换与组件生命周期:

<select id="@ElementId">
    @foreach (var option in Options)
    {
        <option value="@option.serverID.ToString()">@option.server_Name</option>
    }
</select>

@code {
    [Inject] private IJSRuntime JSRuntime { get; set; }
    private DotNetObjectReference<Select2MultiSelect>? _dotNetRef;

    [Parameter] public string ElementId { get; set; } = "select2_" + Guid.NewGuid().ToString("N");
    [Parameter] public List<SelectedServers> Options { get; set; } = new();
    [Parameter] public List<string> SelectedValues { get; set; } = new();
    [Parameter] public EventCallback<List<string>> SelectedValuesChanged { get; set; }

    protected override void OnInitialized()
    {
        _dotNetRef = DotNetObjectReference.Create(this);
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await JSRuntime.InvokeVoidAsync("select2Interop.initializeSelect2", ElementId, _dotNetRef);
            var stringValues = SelectedValues ?? new List<string>();
            await JSRuntime.InvokeVoidAsync("select2Interop.setSelectedValues", ElementId, stringValues);
        }
    }

    [JSInvokable]
    public async Task OnSelect2SelectionChanged(List<string> values)
    {
        SelectedValues = values ?? new List<string>();
        await SelectedValuesChanged.InvokeAsync(SelectedValues);
        StateHasChanged();
    }

    public void Dispose()
    {
        _dotNetRef?.Dispose();
    }

    public class SelectedServers
    {
        public int serverID { get; set; }
        public string server_Name { get; set; } = string.Empty;
    }
}

3. 调整UI使用代码

初始化选中值为非空列表,确保UI能正确刷新:

<Select2MultiSelect Options="@SimilarServers" SelectedValues="@selectedValues" SelectedValuesChanged="@OnSelectedValuesChanged" />
<p>Selected values: @string.Join(", ", selectedValues)</p>

@code {
    private List<string> selectedValues = new();

    private async Task OnSelectedValuesChanged(List<string> newSelectedValues)
    {
        selectedValues = newSelectedValues;
        StateHasChanged();
    }

    private List<Select2MultiSelect.SelectedServers> SimilarServers = new()
    {
        new Select2MultiSelect.SelectedServers { serverID = 1, server_Name = "atapa222" },
        new Select2MultiSelect.SelectedServers { serverID = 2, server_Name = "linuxdata2" }
    };
}

4. 修正JS引用顺序(_Host.cshtml)

确保依赖库加载顺序正确:

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script src="~/assets/js/select2jsinterop.js"></script>
<script src="_framework/blazor.server.js"></script>

关键注意点

  • 必须监听Select2自身的change事件,而非原生select的事件
  • 确保option的value类型与SelectedValues一致(此处将int转为string)
  • JS触发Blazor回调后,需要手动调用StateHasChanged()触发UI更新

内容的提问来源于stack exchange,提问作者ahmed abdelaziz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 09:38:09