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

如何在MVC中基于带父子关系的JSON数据创建带复选框树形结构

Fix Nested Tree View with Checkboxes and Merge jQuery Loops in MVC

Let's tackle your two main issues: building a proper nested tree structure and combining those two $.each loops. The root problem with your current code is that you're appending both domains and modules directly to the same root list, resulting in a flat structure instead of parent-child nesting. Here's how to fix it:

Step 1: Adjust Frontend JavaScript Logic

We'll first group modules by their associated DomainID (so we can quickly find which modules belong to which domain), then loop through domains and nest their corresponding modules directly under them. This merges both loops into a single logical flow.

function GetSelectedDomainValue(DomainID) {
    var adminID = jQuery('[id$=hdnAdminID]').val();
    var roleID = $("#RoleID").val();
    var domainID = $("#DomainID").val();

    $.ajax({
        type: 'POST',
        url: '@Url.Action("BindDomainUserAccess")',
        dataType: 'json',
        data: { RoleID: roleID, DomainID: domainID, AdminID: adminID },
        success: function (data) {
            // 1. Clear existing tree content first to avoid duplicates
            $("#tree").empty();

            // 2. Group modules by DomainID for quick lookup
            const modulesByDomain = {};
            data.ModuleUserViews.forEach(module => {
                if (!modulesByDomain[module.DomainID]) {
                    modulesByDomain[module.DomainID] = [];
                }
                modulesByDomain[module.DomainID].push(module);
            });

            // 3. Loop through domains and build nested structure
            data.DomainUserViews.forEach(domain => {
                // Create parent domain li with checkbox, name, and empty sub-list
                const domainLi = $(`
                    <li class="dd-item">
                        <a href="#">
                            <input type='checkbox' id='${domain.DomainID}' name='DomainUserViews' class='my_chkBox' />
                            ${domain.DomainName}
                        </a>
                        <ul class="dd-list"></ul>
                    </li>
                `);
                
                // Add corresponding modules to the domain's sub-list
                const domainModules = modulesByDomain[domain.DomainID] || [];
                domainModules.forEach(module => {
                    const moduleLi = $(`
                        <li class="dd-item">
                            <a href="#">
                                <input type='checkbox' id='${module.ModuleID}' name='ModuleUserViews' class='my_chkBox' />
                                ${module.ModuleName}
                            </a>
                        </li>
                    `);
                    domainLi.find('.dd-list').append(moduleLi);
                });

                // Append the complete domain node to the root tree
                $("#tree").append(domainLi);
            });
        },
        error: function (ex) {
            alert('Failed to retrieve access data : ' + ex);
        }
    });
}

Step 2: Verify Backend Data Structure

Make sure your ViewRoleModules class (returned by GetRolesDomainModules) includes a DomainID property that matches the DomainID from DomainView. This is critical for grouping modules under their parent domains. If it doesn't exist, update your backend class:

// Ensure ViewRoleModules has a DomainID property to link with parent domains
public class ViewRoleModules
{
    public int ModuleID { get; set; }
    public string ModuleName { get; set; }
    public int DomainID { get; set; } // Add this if missing
    // Other existing properties...
}

Key Improvements Explained:

  • Nested Tree Structure: Each domain now has its own child <ul> where we insert its associated modules, creating the parent-child hierarchy you want (e.g., Doctor → Add/View).
  • Merged Loops: We no longer need separate loops for domains and modules. Instead, we first organize modules by domain, then build the entire tree in one pass through the domains.
  • Better Performance: Using jQuery to build elements before appending reduces repeated DOM updates, making the code more efficient.
  • Clean State: We clear the tree before adding new content to avoid stacking old data when the function runs multiple times.

HTML Remains Unchanged

Your existing HTML structure works perfectly with this new logic—we're just leveraging the nested dd-list class to build the hierarchy.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:49:36