如何使用树创建动态菜单

How to create dynamic menu using tree

我有一个 Angular 项目,但这与 Angular 没有直接关系,我只需要使用树创建动态菜单的逻辑,它也可以类似于 ASP.NET MVC项目。因此,您对 ASP.NET MVC 等的建议也将对我有所帮助。

我使用 PrimeNG Tree 并希望从 MSSQL 数据库中的 table 获取菜单:

菜单 Table(数据已更改为示例用法):

Id     |     Order     |     ParentId     |     Name     |

1            1               0                  Documents
2            1               1                  Work
3            1               2                  Expenses.doc
4            2               2                  Resume.doc
5            2               1                  Home
6            1               5                  Invoices.txt
...

为了填充菜单项,我需要生成一个 JSON 字符串,如下所示:

{
    "data": 
    [
        {
            "label": "Documents",
            "data": "Documents Folder",
            "expandedIcon": "fa-folder-open",
            "collapsedIcon": "fa-folder",
            "children": [{
                    "label": "Work",
                    "data": "Work Folder",
                    "expandedIcon": "fa-folder-open",
                    "collapsedIcon": "fa-folder",
                    "children": [{"label": "Expenses.doc", "icon": "fa-file-word-o", "data": "Expenses Document"}, {"label": "Resume.doc", "icon": "fa-file-word-o", "data": "Resume Document"}]
                },
                {
                    "label": "Home",
                    "data": "Home Folder",
                    "expandedIcon": "fa-folder-open",
                    "collapsedIcon": "fa-folder",
                    "children": [{"label": "Invoices.txt", "icon": "fa-file-word-o", "data": "Invoices for this month"}]
                }]
        },
        ... //omitted for brevity
    ]
}

所以,我真的不知道逻辑和数据库table 设计(菜单)。我应该在控制器或其他地方生成上面的 JSON 吗?您能否就此问题提出 post 建议和示例方法?

您的数据库 Menu table 可以使用 PrimeNG Tree 插件生成树视图,除了您可能希望为 [=15] 添加一个额外的 属性 =] 属性 如果你愿意的话。但是,我建议您使 ParentId 属性 可为空,以便您的顶级项目 (Documents) 具有 null 值而不是 0.

为了以这种格式传递 json,您的模型需要

public class MenuVM
{
    public int Id { get; set; } // this is only used for grouping
    public string label { get; set; }
    public string expandedIcon { get; set; }
    public string collapsedIcon { get; set; }
    public string icon { get; set; }
    public IEnumerable<MenuVM> children { get; set; }
}

您还可以包括其他属性,例如

public string data { get; set; }

匹配api

中的属性

您还需要 data 属性

的父模型
public class TreeVM
{
    public IEnumerable<MenuVM> data { get; set; }
}

要生成模型,您的控制器代码将是(注意这是基于 ParentId 字段是 null 如上所述的顶级项目)

// Sort and group the menu items
var groups = db.Menus
    .OrderBy(x => x.ParentId).ThenBy(x => x.Order)
    .ToLookup(x => x.ParentId, x => new MenuVM
    {
        Id = x.Id,
        label = x.Name
    });
// Assign children
foreach (var item in groups.SelectMany(x => x))
{
    item.children = groups[item.Id].ToList();
    if (item.children.Any())
    {
        .... // apply some logic if there a child items, for example setting 
             // the expandedIcon and collapsedIcon properties
    }
    else
    {
        .... // apply some logic if there are no child items, for example setting 
             // the icon properties - e.g. item.icon = "fa-file-word-o";
    }
}
// Initialize model to be passed to the view
TreeVM model = new TreeVM
{
    data = groups[null].ToList();
}
return Json(model, JsonRequestBehavior.AllowGet);

对于您的图标,您应该考虑一些 const 值或 enum 而不是硬编码字符串。