我目前有一个名为 _SubMenu.cshtml 的共享文件,但这需要在我的所有视图中实现,我发现这很麻烦并且可能没有必要(?)。
因此,我想知道是否有一种“正确”的方式来实现共享主布局文件中的上下文相关菜单,该菜单会根据您在 RenderBody() 中的渲染视图而改变?
每个单独的控制器是否应该处理这个,或者这是要在其他地方处理的东西?
我目前有一个名为 _SubMenu.cshtml 的共享文件,但这需要在我的所有视图中实现,我发现这很麻烦并且可能没有必要(?)。
因此,我想知道是否有一种“正确”的方式来实现共享主布局文件中的上下文相关菜单,该菜单会根据您在 RenderBody() 中的渲染视图而改变?
每个单独的控制器是否应该处理这个,或者这是要在其他地方处理的东西?
您可以创建一个特定于控制器的_SubMenu.cshtml
,如下所示:
~/Views/Controller1/_SubMenu.cshtml
~/Views/Controller2/_SubMenu.cshtml
~/Views/Controller2/_SubMenu.cshtml
然后在你的Layout
:
@Html.Partial("_SubMenu")
然后 View-Engine 将_SubMenu
根据当前控制器获取适当的。
或者,如果您坚持使用单个_SubMenu
部分,您可以switch
在当前控制器上并呈现适当的 html:
<div id="menu">
@switch (this.ViewContext.RouteData.Values["controller"].ToString().ToLower())
{
case "controller1":
<a href="#">Controller 1 Action</a>
<a href="#">Another Controller 1 Action</a>
break;
case "controller2":
<a href="#">Controller 2 Action</a>
<a href="#">Another Controller 2 Action</a>
break;
}
</div>
您可以使用子操作。这个想法是有一个这样的控制器动作:
public class SomeController: Controller
{
[ChildActionOnly]
public ActionResult SomeAction()
{
SomeViewModel model = ...
return PartialView(model);
}
}
然后你就会有一个对应的局部视图:
@model MyViewModel
...
可以包含在您的布局或视图中:
@Html.Action("SomeAction", "SomeController")
Phil Haack 在这里写了关于儿童行动的博客:http: //haacked.com/archive/2009/11/17/aspnetmvc2-render-action.aspx
您还可以对特定 ViewData || 进行主/共享布局检查 ViewBag 值。
@if(ViewData["_ContextMenuList_"] is List<ContextMenuItem>) {
/// render the rest of the menu directly or in a strongly typed partial view.
}
我将使用具有菜单文本、操作、控制器、htmlClass 和一些路由值的对象列表。
public class ContexMenuItem
{
public string MenuText { get; set; }
public string Action { get; set; }
public string Controller { get; set; }
public object RouteValues { get; set; }
public object HtmlValues { get; set; }
}
然后仅在有意义的控制器操作中设置此值,并用相关的上下文数据填充它。
// Inside some controller action.
//asuming some how you already got your client's info.
var contextMenu = new List<ContexMenuItem>();
contextMenu.Add(new ContexMenuItem()
{
MenuText = "View More " + client.Name + "'s Info",
Action = "ViewMore",
Controller = "Clients",
HtmlValues = null,
RouteValues = new { id = client.ID }
});
contextMenu.Add(new ContexMenuItem()
{
MenuText = "Send a message to " + client.Name ,
Action = "SendMessage",
Controller = "Inbox",
HtmlValues = null,
RouteValues = new { id = client.ID }
});
ViewData["_ContextMenuList_"] = contextMenu;
这可能很乏味,因为您必须在给定控制器上的所有相关操作中执行此操作。如果是这种情况,将该代码重构为控制器内部的私有函数,并在应用时调用它。
有些人可能会争辩说这些数据应该始终在 Model 类上,在这种情况下,我认为这是一个上下文数据,不一定是手头模型的一部分。通过简单地将渲染代码放在不了解模型的主类中,它还使编码更容易。它很像一些 MVC 模板上的 _LogOnPartial.cshtml。