如何使用树创建动态菜单

时间:2017-10-04 08:39:56

标签: asp.net-mvc angular primeng

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

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

菜单表(数据已更改,例如用法):

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
    ]
}

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

1 个答案:

答案 0 :(得分:2)

您的数据库Menu表可以使用 PrimeNG Tree插件生成树视图,但您可能希望为data属性添加其他属性。不过,我建议您将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而不是硬编码字符串。