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

如何在ASP.NET MVC/Razor中实现弹窗式动态加载TreeView

替换ASP.NET MVC的Datalist为弹窗TreeView(或文本框+浏览按钮)

现有代码回顾

原CSHTML代码(生成带datalist的文本框):

<div class="data-input-group">
    @Html.LabelFor(m => m.SourceTag)
    @Html.EditorFor(m => m.SourceTag, new { htmlAttributes = new { list = "source-tag-list", style = "width: 750px" } })
    @Html.ValidationMessageFor(m => m.SourceTag)
</div>
<datalist id="source-tag-list"></datalist>

最终生成的HTML:

<div class="data-input-group">
    <label for="SourceTag">Source Tag Name</label>
    <input class="text-box single-line valid" data-val="true" data-val-required="The Source Tag Name field is required." id="SourceTag" list="source-tag-list" name="SourceTag" style="width: 750px" type="text" value="" aria-describedby="SourceTag-error" aria-invalid="false">
    <span class="field-validation-valid" data-valmsg-for="SourceTag" data-valmsg-replace="true"></span>
</div>
<datalist id="source-tag-list">
<option value="This is drop down level 1.This is drop down level 2."></option>
</datalist>

方案一:文本框+浏览弹窗(简单实现)

1. 修改CSHTML结构

添加浏览按钮,移除原datalist:

<div class="data-input-group">
    @Html.LabelFor(m => m.SourceTag)
    @Html.EditorFor(m => m.SourceTag, new { htmlAttributes = new { style = "width: 750px", @readonly = "readonly" } })
    @Html.ValidationMessageFor(m => m.SourceTag)
    <button type="button" id="browseSourceTag" class="btn btn-primary ml-2">浏览</button>
</div>

2. 添加Bootstrap模态框(弹窗容器)

在页面末尾添加弹窗代码:

<div class="modal fade" id="tagTreeModal" tabindex="-1" role="dialog" aria-labelledby="tagTreeModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="tagTreeModalLabel">选择Source Tag</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                <div id="sourceTagTree"></div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
                <button type="button" class="btn btn-primary" id="confirmTagSelect">确认选择</button>
            </div>
        </div>
    </div>
</div>

3. 后端添加懒加载接口

在对应控制器中实现返回子节点的接口:

// 假设标签实体类为SourceTag,包含Id、Name、ParentId字段
public JsonResult GetChildTags(int parentId = 0)
{
    var childTags = db.SourceTags
        .Where(t => t.ParentId == parentId)
        .Select(t => new {
            id = t.Id,
            text = t.Name,
            children = db.SourceTags.Any(c => c.ParentId == t.Id)
        }).ToList();

    return Json(childTags, JsonRequestBehavior.AllowGet);
}

4. 前端脚本实现交互

引入jQuery和jsTree(可通过NuGet或CDN添加),添加以下脚本:

$(function() {
    // 初始化懒加载树
    $('#sourceTagTree').jstree({
        'core': {
            'data': function(node, callback) {
                var parentId = node.id === '#' ? 0 : node.id;
                $.get('/YourController/GetChildTags', { parentId: parentId }, function(data) {
                    callback.call(this, data);
                });
            },
            'multiple': false
        }
    });

    // 打开弹窗
    $('#browseSourceTag').click(function() {
        $('#tagTreeModal').modal('show');
    });

    // 确认选择后回填文本框
    $('#confirmTagSelect').click(function() {
        var selectedNode = $('#sourceTagTree').jstree('get_selected')[0];
        if (selectedNode) {
            $('#SourceTag').val($('#sourceTagTree').jstree('get_text', selectedNode));
            $('#tagTreeModal').modal('hide');
        }
    });
});

方案二:无插件手动实现树(极简版)

如果不想用第三方插件,可手动实现简单懒加载树:

1. 修改模态框内的树容器

<div class="modal-body">
    <ul id="sourceTagTree" class="tree-view">
        <!-- 根节点将通过脚本加载 -->
    </ul>
</div>

2. 前端脚本实现懒加载

$(function() {
    // 加载根节点
    loadChildNodes(0, $('#sourceTagTree'));

    $('#browseSourceTag').click(function() {
        $('#tagTreeModal').modal('show');
    });

    $('#confirmTagSelect').click(function() {
        var selectedText = $('.tree-view .selected').text();
        if (selectedText) {
            $('#SourceTag').val(selectedText);
            $('#tagTreeModal').modal('hide');
        }
    });

    // 加载子节点函数
    function loadChildNodes(parentId, container) {
        $.get('/YourController/GetChildTags', { parentId: parentId }, function(data) {
            container.empty();
            $.each(data, function(index, tag) {
                var li = $('<li>' + tag.text + '</li>');
                if (tag.children) {
                    var expandBtn = $('<span class="expand-btn">+</span>');
                    li.prepend(expandBtn);
                    var childUl = $('<ul class="child-nodes"></ul>');
                    li.append(childUl);

                    expandBtn.click(function() {
                        if (childUl.is(':empty')) loadChildNodes(tag.id, childUl);
                        childUl.toggle();
                        $(this).text($(this).text() === '+' ? '-' : '+');
                    });
                }

                li.click(function(e) {
                    e.stopPropagation();
                    $('.tree-view .selected').removeClass('selected');
                    $(this).addClass('selected');
                });
                container.append(li);
            });
        });
    }
});

3. 添加基础样式

.tree-view {
    list-style: none;
    padding-left: 20px;
}
.tree-view .child-nodes {
    display: none;
    list-style: none;
    padding-left: 20px;
}
.expand-btn {
    cursor: pointer;
    margin-right: 5px;
    color: #007bff;
}
.tree-view .selected {
    background-color: #e9ecef;
    font-weight: bold;
}

注意事项

  • 将YourController替换为实际的控制器名称
  • 调整数据库查询逻辑以匹配你的业务实体字段
  • 确保项目已引入Bootstrap和jQuery(可通过NuGet安装对应包)
  • 若允许用户手动输入文本,可移除文本框的readonly属性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 20:25:32