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

ASP.NET Core MVC中jsTree联动产品表格更新问题求助

解决方案

一、控制器Node方法的返回方案

你有两种实用选择,根据前端实现偏好来选:

1. 返回JSON格式的产品数据

适合前端自行拼接表格DOM的场景,控制器查询数据后序列化为JSON返回:

public IActionResult Node(int categoryId)
{
    // 用EF Core筛选对应分类的产品,按需返回表格所需字段
    var products = _context.Products
        .Where(p => p.CategoryId == categoryId)
        .Select(p => new 
        {
            Id = p.Id,
            ProductName = p.ProductName,
            Price = p.Price.ToString("C"),
            Description = p.Description
        })
        .ToList();

    return Json(products);
}

如果需要支持分页、排序,也可以返回包含分页信息的复合对象(比如{ Total: totalCount, Data: products })。

2. 返回渲染好的表格部分视图

不想前端拼接HTML的话,让控制器返回预渲染的表格片段:
首先创建部分视图_ProductTable.cshtml,传入List<Product>模型:

<table class="table table-striped">
    <thead>
        <tr>
            <th>ID</th>
            <th>产品名称</th>
            <th>价格</th>
            <th>描述</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var product in Model)
        {
            <tr>
                <td>@product.Id</td>
                <td>@product.ProductName</td>
                <td>@product.Price.ToString("C")</td>
                <td>@product.Description</td>
            </tr>
        }
    </tbody>
</table>

然后控制器方法返回该视图(建议用异步查询优化性能):

public async Task<IActionResult> Node(int categoryId)
{
    var products = await _context.Products
        .Where(p => p.CategoryId == categoryId)
        .ToListAsync();

    return PartialView("_ProductTable", products);
}

二、前端实现节点切换时的表格更新

结合jsTree的changed事件,发送AJAX请求并更新右侧内容:

1. 对应JSON返回的前端逻辑

先在页面右侧添加表格容器:

<div id="productTableWrap">
    <table class="table table-striped" id="productTable">
        <thead>
            <tr>
                <th>ID</th>
                <th>产品名称</th>
                <th>价格</th>
                <th>描述</th>
            </tr>
        </thead>
        <tbody id="productTableBody">
            <tr><td colspan="4">请选择左侧分类查看产品</td></tr>
        </tbody>
    </table>
</div>

然后在jsTree的切换事件中处理:

$('#jstree').on('changed.jstree', function (e, data) {
    const categoryId = data.selected[0];
    const tableBody = $('#productTableBody');

    // 未选中节点时重置提示
    if (!categoryId) {
        tableBody.empty();
        tableBody.append('<tr><td colspan="4">请选择左侧分类查看产品</td></tr>');
        return;
    }

    // 发送AJAX请求
    $.ajax({
        url: '/YourController/Node', // 替换为你的控制器名称
        type: 'GET',
        data: { categoryId: categoryId },
        beforeSend: function () {
            // 显示加载状态
            tableBody.empty();
            tableBody.append('<tr><td colspan="4">加载中...</td></tr>');
        },
        success: function (products) {
            tableBody.empty();
            // 遍历生成表格行
            $.each(products, function (index, product) {
                const row = `<tr>
                                <td>${product.Id}</td>
                                <td>${product.ProductName}</td>
                                <td>${product.Price}</td>
                                <td>${product.Description}</td>
                            </tr>`;
                tableBody.append(row);
            });
            // 无产品时显示提示
            if (products.length === 0) {
                tableBody.append('<tr><td colspan="4">当前分类暂无产品</td></tr>');
            }
        },
        error: function () {
            tableBody.empty();
            tableBody.append('<tr><td colspan="4">加载产品数据失败,请重试</td></tr>');
        }
    });
});

2. 对应部分视图返回的前端逻辑

右侧用一个空容器即可:

<div id="productTableWrap">
    <p>请选择左侧分类查看产品</p>
</div>

然后AJAX请求直接替换容器内容:

$('#jstree').on('changed.jstree', function (e, data) {
    const categoryId = data.selected[0];
    const container = $('#productTableWrap');

    if (!categoryId) {
        container.html('<p>请选择左侧分类查看产品</p>');
        return;
    }

    $.ajax({
        url: '/YourController/Node',
        type: 'GET',
        data: { categoryId: categoryId },
        beforeSend: function () {
            container.html('<p>加载中...</p>');
        },
        success: function (html) {
            container.html(html);
            // 无产品时追加提示
            if ($(html).find('tbody tr').length === 0) {
                container.append('<p class="mt-2">当前分类暂无产品</p>');
            }
        },
        error: function () {
            container.html('<p>加载产品数据失败,请重试</p>');
        }
    });
});

三、额外注意事项

  • 确保控制器路由正确:如果控制器使用了路由特性(比如[Route("products")]),AJAX的url要对应调整(比如'/products/Node')。
  • 处理分类层级:如果需要显示当前分类及所有子分类的产品,要修改EF Core查询逻辑,比如用递归查询获取所有子分类ID,再筛选产品。
  • 防重复请求:可以在发送AJAX前取消之前的请求,避免多次切换节点导致的请求堆积。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 15:54:49