【问题标题】:How to create dynamic menu using tree如何使用树创建动态菜单
【发布时间】:2017-10-04 22:13:43
【问题描述】:

我有一个 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
    ]
}

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

【问题讨论】:

  • @StephenMuecke 嗨 Stephane,对不起,我对这个问题真的没有经验。如果你有时间,你能举个例子吗?或者给我推荐一个网络上的示例使用页面?在此先感谢...
  • @StephenMuecke 亲爱的 Stephane,我病了,无法查看您的回答。你为什么删除它?你能再发一次吗? :((

标签: asp.net-mvc angular primeng


【解决方案1】:

您的数据库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,而不是硬编码字符串。

【讨论】:

  • 哦,非常感谢!..我会尽快尝试并通知您结果...已投票+
  • 我只能假设你没有包含using System.Linq;
  • .ToLookup() 类似于 .GroupBy() - 即它通过 ParentId 属性对每条记录进行分组。两者之间的区别在this question 的答案中进行了解释。此时,我们有一个Key=null 组包含一条记录(文档)和一个Key=1 组包含两条记录(工作和家庭)等
  • 这就是我们后面用来为每个菜单分配Children的集合。但是现在我们需要获取每条记录才能分配Children。我们可以再次调用数据库,但我们使用.SelectMany() 将项目再次展平为单个集合。
  • 最后,我们只想要“顶级”项目 - 带有 ParentId=null 的项目(因为它现在包含填充 Children 属性)所以我们使用 groups[null] - 它查找与Key=null. (note that if you had not changed ParentId` 到int? 的组,并且根据您的原始代码,“顶级”具有ParentId=0,那么它将是groups[0])
猜你喜欢
  • 1970-01-01
  • 2013-03-12
  • 1970-01-01
  • 2015-04-08
  • 1970-01-01
  • 2021-10-06
  • 2014-11-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多