我创建了第N级动态菜单递归方法,用于创建菜单。
如上图所示,内容将返回ParialView,名为" _Menu.cshtml"并且此部分视图文件为空。
然后有一个_LayoutPage.Cshtml
$('#element').functionWithParameters('some parameter', 'another parameter');
它成功地将结果放入浏览器,但是如上所述的纯文本,可以在下面看到。
我如何使这些行为像链接,而不是像明文?帮助将不胜感激。谢谢:))
答案 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; }
}