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

Blazor WASM中添加myList非空判断后JQuery UI Sortable为何失效?

问题原因分析
  1. 判断顺序错误:你代码示例2中的判断顺序myList.Any() && myList != null完全颠倒了——当myList为null时,会先执行Any()方法,直接触发空引用异常。正确的顺序应该是先判断myList != null,再判断Any(),利用C#的短路求值特性,避免空引用。

  2. jQuery初始化时机不匹配:这是导致排序失效的核心原因。Blazor组件的渲染是异步的:

    • 当myList初始为null或空列表时,<ul id="sort">不会被渲染到DOM中;
    • 如果你的jQuery Sortable初始化代码是在页面加载时执行的,此时找不到#sort元素,初始化逻辑不会生效;
    • 后续myList加载数据后,<ul>被渲染出来,但jQuery已经完成了初始化,不会自动重新绑定,所以拖拽功能失效。
解决方案

方案1:修正判断顺序 + 利用Blazor生命周期初始化Sortable

1. 修正组件渲染逻辑

确保先判断myList非空,再判断是否有元素:

@if(myList != null && myList.Any()) 
{      
      <ul id="sort">  
      @foreach(var item in myList) {
          <li class="default">@item.Property1</li>  
          <li class="default">@item.Property2</li>  
          <li class="default">@item.Property3</li>  
      }
      </ul>   
}

2. 在Blazor生命周期中初始化Sortable

使用OnAfterRenderAsync方法,确保<ul>渲染到DOM后再执行jQuery初始化:

@inject IJSRuntime JSRuntime

@code {
    private List<Something> myList;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        // 首次渲染或列表有数据时,初始化Sortable
        if ((firstRender || (myList != null && myList.Any())) && await JSRuntime.InvokeAsync<bool>("elementExists", "sort"))
        {
            await JSRuntime.InvokeVoidAsync("initSortable");
        }
    }
}

3. 定义jQuery辅助函数

在wwwroot/js目录下创建sortable.js,并在index.html中引入:

function elementExists(id) {
    return document.getElementById(id) !== null;
}

function initSortable() {
    // 先销毁已有的Sortable实例,避免重复绑定
    $("#sort").sortable("destroy");
    $("#sort").sortable({
        // 可选:配置排序后的回调,将顺序同步回Blazor
        update: function(event, ui) {
            var order = $("#sort").sortable("toArray");
            DotNet.invokeMethodAsync("YourAssemblyName", "UpdateSortOrder", order);
        }
    });
    $("#sort").disableSelection();
}

方案2:始终渲染<ul>(推荐)

不管列表是否有数据,都将<ul>保留在DOM中,仅控制显示/隐藏,确保jQuery能找到元素初始化:

<ul id="sort" style="@(myList?.Any() == true ? "display: block" : "display: none")">  
    @if(myList != null) {
        @foreach(var item in myList) {
            <li class="default">@item.Property1</li>  
            <li class="default">@item.Property2</li>  
            <li class="default">@item.Property3</li>  
        }
    }
</ul>

这种方式下,jQuery初始化代码可以直接放在页面加载时执行,无需依赖Blazor生命周期,因为<ul>始终存在于DOM中。

额外注意事项

  • 如果你初始化了空列表private List<Something> myList = new List<Something>();,那么myList != null永远为true,此时只需判断myList.Any()即可;
  • 当myList数据更新后,若需要重新触发Sortable初始化,可以在数据更新后调用StateHasChanged(),触发OnAfterRenderAsync执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 19:40:09