Mvc动态菜单填充纯文本

时间:2017-03-29 07:33:35

标签: asp.net-mvc asp.net-mvc-4 menu plaintext

我创建了第N级动态菜单递归方法,用于创建菜单。

enter image description here

如上图所示,内容将返回ParialView,名为" _Menu.cshtml"并且此部分视图文件为空。

enter image description here

然后有一个_LayoutPage.Cshtml

$('#element').functionWithParameters('some parameter', 'another parameter');

它成功地将结果放入浏览器,但是如上所述的纯文本,可以在下面看到。

enter image description here

我如何使这些行为像链接,而不是像明文?帮助将不胜感激。谢谢:))

2 个答案:

答案 0 :(得分:4)

虽然战争解决了我上面的问题。但我仍然想回答上述答案看似复杂的人。 以最简单的方式在MVC中从数据库填充动态导航菜单。

控制器中的

    public ActionResult Index()
{
    Menu menu_ = new Menu();
    ViewBag.Menu = menu_.getMenuList();
    return View();
}
_layoutpage.Cshtml中的

        <div id="Menu">
       @{ List<WebApplicationMVC.Core.Models.menu> All = ViewBag.Menu;}
        <ul>
            @foreach (var One in All.Where(m => m.ParentId == 0))
            {
                List<WebApplicationMVC.Core.Models.menu> Child = All.Where(m => One.id == m.ParentId).ToList();
                if (Child.Count > 0)
                {
                    if(One.ActionLink == "Yes")
                    {
                        <li>
                            @Html.ActionLink(One.Name, One.Action, One.Controller)
                            @SubMenu(One, All)
                        </li>
                    }
                    else
                    {
                        <li>
                            @One.Name;
                            @SubMenu(One, All)
                        </li>
                    }
                }
                else
                {
                    <li>@Html.ActionLink(One.Name, One.Action, One.Controller)</li>
                }
            }
        </ul>

        @helper SubMenu(WebApplicationMVC.Core.Models.menu Object, List<WebApplicationMVC.Core.Models.menu> List)
        {
        List<WebApplicationMVC.Core.Models.menu> subChilds = (from a in List where Object.id == a.ParentId select a).ToList();
        <ul>
            @foreach (var subOne in subChilds)
            {
                List<WebApplicationMVC.Core.Models.menu> InnerChilds = (from a in List where subOne.id == a.ParentId select a).ToList();
                if (InnerChilds.Count > 0)
                {
                    if (subOne.ActionLink == "Yes")
                    {
                        <li>
                            @Html.ActionLink(subOne.Name, subOne.Action, subOne.Controller)
                            @SubMenu(subOne, List)
                        </li>
                    }
                    else
                    {
                        <li>
                            @subOne.Name
                            @SubMenu(subOne, List)
                        </li>
                    }
                }
                else
                {
                    <li>@Html.ActionLink(subOne.Name, subOne.Action, subOne.Controller)</li>
                }
            }
        </ul>
        }
    </div>

答案 1 :(得分:2)

我对这一点采取了更为复杂的观点。

在我放置的布局中......

 @if (Model != null && Model is Core.Objects.Entities.CMS.Page)
 {
                @Html.Action("Menu", new MenuOptions { IsRootMenu = true, ForPageId = Model.Id, Depth = 3 })
 }

我首先检查用户是否已登录,因此“在托管页面上”只有在模型具有特定类型“Core.Objects.Entities.CMS.Page”时才会发生。

然后我调用@ Html.Action在我的控制器上调用以下子操作,并构建我的菜单选项......

[HttpGet]
[ChildActionOnly]
[Route("~/Menu")]
public ActionResult Menu(MenuOptions options)
{
    //TODO: consider other complex menuing scenarios like a popup / tree based structures
    //      New api calls may be needed to support more complex menuing scenarios

    // TODO: figure out how to build these, perhaps with a string builder
    var expand = string.Empty;
    if (options.Depth > 0)
    {
        switch (options.Depth)
        {
            case 1: expand = "?$expand=PageInfo,Pages($expand=PageInfo)"; break;
            case 2: expand = "?$expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo))"; break;
            case 3: expand = "?$expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo)))"; break;
            case 4: expand = "?$expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo,Pages($expand=Pages($expand=PageInfo))))"; break;
            case 5: expand = "?$expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo,Pages($expand=PageInfo)))))"; break;
        }
    }

    var query = options.IsRootMenu
        ? "Core/Page/MainMenuFor(id=" + options.ForPageId + ")" + expand
        : "Core/Page/ChildrenOf(id=" + options.ForPageId + ")" + expand;

    var items = Task.Run(() => Api.GetODataCollection<Page>(query)).Result;

    return PartialView(new MenuViewModel { Origin = options.ForPageId, Pages = items });
}

在我的情况下,这个区域需要一些工作,我应该用一些构建查询的更智能的循环代码替换该case语句。

简而言之,虽然所有这一切都是将我的OData API上的Page对象层次结构拉到我传入的选项所确定的深度,因为菜单往往会有所不同,有些是单级别选项,其他有多层次但是我想要一个可重复使用的菜单系统

完成后我可以获取OData结果并为菜单视图构建一个模型,看起来像这样......

@model MenuViewModel
@if (Model.Pages != null)
{
    <ul class="menu">
        @foreach (var p in Model.Pages)
        {
            Html.RenderPartial("MenuItem", new MenuItemViewModel { Page = p, Origin = Model.Origin });
        }
    </ul>
}

菜单视图设置了一个根列表并为每个子页面渲染一个子项,我打算在某个时候展开这个视图,比如吐出父页面,这可能是我在控制器中拉出的OData结果

最后一个难题是菜单项视图,它处理渲染每个单独的菜单项......

@model MenuItemViewModel
<li>
    <a href="@Html.Raw("/" + Model.Page.Path)" @CurrentItem(Model.Page)>@Html.PageInfo(Model.Page).Title</a>
    @if (Model.Page.Pages != null && Model.Page.Pages.Any())
    {
        <ul class="submenu">
        @foreach (var p in Model.Page.Pages)
        {
            Html.RenderPartial("MenuItem", new MenuItemViewModel { Page = p, Origin = Model.Origin });
        }
        </ul>
    }
</li>

@functions{
    MvcHtmlString CurrentItem(Core.Objects.Entities.CMS.Page p)
    {
        if (Model.Origin == p.Id) return new MvcHtmlString("class='selected'");
        return null;
    }
}

完成所有这些后,我最终得到了一组嵌套的列表,然后我使用CSS来处理弹出窗口或动态扩展等内容。

这个功能还不是很完整,我需要确保用一个类或者其他东西处理“标记当前项目”,这样我可以用不同的方式设置它,并且还有一些我想添加的其他菜单方案,但是我已经考虑过以某种方式重复使用这个html结构进行树视图,但是从长远来看树可能会更多一些,但是如果它可配置,那么像将一个图像放在菜单项旁边似乎是一个很好的逻辑改进:)

我忘记输入的最后一件事是控制器中菜单操作使用的菜单选项模型......

public class MenuOptions
{
    public bool IsRootMenu { get; set; }
    public int ForPageId { get; set; }
    public int Depth { get; set; }
}
相关问题