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

Blazor Server(.NET 7)下拉框控制输入框显隐:JS/jQuery或C#方案

Blazor Server(.NET Core 7)下拉框联动显示/隐藏输入框问题解决

问题背景

开发基于.NET Core 7的Blazor Server应用时,在serverNames.Razor组件中尝试用jQuery实现下拉框选择后显示/隐藏输入框,出现Cannot read properties of null (reading 'removeChild')错误。

组件HTML结构

<div class="col-md-4 col-lg-3">
    <div class="form-group" style="display:flex; flex-direction: row; justify-content: center; align-items: center">
        <label for="example-text-input" class="col-3 col-form-label">SearchBy</label>
        <select id="ddlOptionSearch" class="form-select">
            <option value="0">--Select--</option>
            <option value="1">Server Name</option>
            <option value="2">Server Type</option>
        </select>
    </div>
</div>

<div class="col-md-3 col-lg-2">
    <div id="dvSearch" style="display: none">
        Server Number:
        <input type="text" class="form-control" id="txtServerName" />
    </div>
</div>

所用jQuery脚本

<script type="text/javascript">
    $(function () {
        $("#ddlOptionSearch").change(function () {
            if ($(this).val() == "Server Name") {
                console.log("server name selected");
                $("#dvSearch").show();
            } else {
                $("#dvSearch").hide();
            }
        });
    });
</script>

报错信息

Uncaught (in promise) TypeError: Cannot read properties of null (reading 'removeChild')
    at j (blazor.server.js:1:17509)
    at blazor.server.js:1:20768
    at se.updateComponent (blazor.server.js:1:20793)
    at blazor.server.js:1:118191
    at Hn.processBatch (blazor.server.js:1:118563)
    at Ft.<anonymous> (blazor.server.js:1:133366)
    at Ft._invokeClientMethod (blazor.server.js:1:75072)
    at Ft._processIncomingData (blazor.server.js:1:72696)
    at Ft.connection.onreceive (blazor.server.js:1:67009)
    at i.onmessage (blazor.server.js:1:51322)
blazor.server.js:1 [2023-03-13T13:25:21.637Z] Error: System.AggregateException: One or more errors occurred. (TypeError: Cannot read properties of null (reading 'removeChild'))
 ---&gt; System.InvalidOperationException: TypeError: Cannot read properties of null (reading 'removeChild')
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.InvokeRenderCompletedCallsAfterUpdateDisplayTask(Task updateDisplayTask, Int32[] updatedComponents)
   --- End of inner exception stack trace ---

解决方案

原因分析

  1. DOM渲染冲突:Blazor Server通过SignalR双向绑定管理DOM,组件会频繁重新渲染,jQuery直接操作DOM会和Blazor的渲染机制冲突——当Blazor重新渲染时,jQuery修改过的DOM元素可能已被销毁,导致找不到元素抛出错误。
  2. 逻辑错误:下拉框选项的value是数字字符串("1"/"2"),但脚本中判断的是等于文本"Server Name",永远不会触发显示逻辑。

方案一:Blazor原生C#实现(推荐)

利用Blazor的数据绑定和条件渲染,完全由框架管理DOM,避免冲突:

<div class="col-md-4 col-lg-3">
    <div class="form-group" style="display:flex; flex-direction: row; justify-content: center; align-items: center">
        <label class="col-3 col-form-label">SearchBy</label>
        <select @bind="SelectedSearchOption" class="form-select">
            <option value="0">--Select--</option>
            <option value="1">Server Name</option>
            <option value="2">Server Type</option>
        </select>
    </div>
</div>

<div class="col-md-3 col-lg-2">
    @if (SelectedSearchOption == 1)
    {
        <div>
            Server Number:
            <input type="text" class="form-control" @bind="ServerName" />
        </div>
    }
</div>

@code {
    // 绑定下拉框选中值
    private int SelectedSearchOption { get; set; } = 0;
    // 绑定输入框内容
    private string ServerName { get; set; } = string.Empty;
}

说明

  • 使用@bind将下拉框选中值绑定到C#属性SelectedSearchOption
  • 通过@if条件渲染控制输入框的显示/隐藏,完全符合Blazor的渲染机制
  • 数据直接绑定到C#属性,方便后续业务逻辑调用

方案二:修正后的jQuery实现(不推荐,仅作兼容参考)

若必须使用jQuery,需解决DOM渲染时机和逻辑错误问题:

  1. 组件代码:通过JSInterop在组件渲染完成后绑定事件
<div class="col-md-4 col-lg-3">
    <div class="form-group" style="display:flex; flex-direction: row; justify-content: center; align-items: center">
        <label for="example-text-input" class="col-3 col-form-label">SearchBy</label>
        <select id="ddlOptionSearch" class="form-select">
            <option value="0">--Select--</option>
            <option value="1">Server Name</option>
            <option value="2">Server Type</option>
        </select>
    </div>
</div>

<div class="col-md-3 col-lg-2">
    <div id="dvSearch" style="display: none">
        Server Number:
        <input type="text" class="form-control" id="txtServerName" />
    </div>
</div>

@code {
    [Inject]
    private IJSRuntime JSRuntime { get; set; }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        // 仅在首次渲染完成后绑定事件
        if (firstRender)
        {
            await JSRuntime.InvokeVoidAsync("initSearchDropdown");
        }
    }
}
  1. 布局页脚本:在_Layout.cshtml中添加脚本(Blazor Server无index.html,布局页负责引入全局资源)
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script>
    function initSearchDropdown() {
        // 先解绑再绑定,避免重复注册事件
        $("#ddlOptionSearch").off("change").on("change", function () {
            // 匹配选项的value值"1",而非文本
            if ($(this).val() === "1") {
                $("#dvSearch").show();
            } else {
                $("#dvSearch").hide();
            }
        });
    }
</script>

说明

  • 在OnAfterRenderAsync中调用JS方法,确保DOM已渲染完成
  • 使用.off("change").on("change")避免重复绑定事件
  • 修正判断条件为匹配选项的value值,而非显示文本

内容的提问来源于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.28 02:07:14