如何使用树创建动态菜单 [英] How to create dynamic menu using tree

查看:52
本文介绍了如何使用树创建动态菜单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an Angular project but this is not directly related to Angular and I just need the logic of create dynamic menu using tree that can also be similar as in ASP.NET MVC project. So, your suggestion for ASP.NET MVC, etc. will also be helpfu for me.

我使用 PrimeNG树 ,并希望获得MSSQL数据库中的表中的菜单:

I use PrimeNG Tree and want to obtain menu from a table in MSSQL database:

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

Menu Table (the data was changed for example usage):

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字符串,如下所示:

In order to populate the menu items, I need to generate a JSON string as shown below:

{
    "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吗?您能否发表有关此问题的建议和示例方法?

So, I have really no idea about the logic and database table design (menus). Should I generate the JSON above on the Controller or another place? Could you please post suggestions and sample approaches regarding to this issue?

推荐答案

您的数据库Menu表可以使用 PrimeNG Tree 插件,不同之处在于,如果需要,您可能希望为data属性包括一个附加属性.但是,我建议您将ParentId属性设置为可为空,以便您的顶级项目(Documents)具有一个null值,而不是0.

Your database Menu table is fine to generate the treeview using the PrimeNG Tree plugin except that you may want to include an additional property for the data property if you want. I would however suggest you make the ParentId property nullable so that your top level item (Documents) has a null value rather that 0.

要以这种格式传递json,您的模型必须为

In order to pass json in that format, your model need to be

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

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

You might also include other properties such as

public string data { get; set; }

以匹配api中的属性

您还需要data属性的父模型

public class TreeVM
{
    public IEnumerable<MenuVM> data { get; set; }
}

要生成模型,您的控制器代码将是(请注意,这是基于上面提到的顶级项目的ParentId字段为null)

To generate the model, you controller code would be (note this is based on the ParentId field being null for the top level item as noted above)

// 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而不是对字符串进行硬编码.

For your icons, you should consider some const values or an enum rather than hard-coding strings.

这篇关于如何使用树创建动态菜单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆