Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
347 views
in Technique[技术] by (71.8m points)

asp.net mvc - How to create dynamic menu using tree

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.

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
...

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

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

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

to match the properties in the api

You also need a parent model for the data property

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

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

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...