是否可以在主布局中使用上下文相关菜单?

时间:2013-10-07 06:53:38

标签: asp.net-mvc-4

我目前有一个名为_SubMenu.cshtml的共享文件,但这需要在我的所有视图中实现,我发现这些视图很麻烦且可能不必要(?)。

因此,我想知道在共享主布局文件中是否有“正确”的方法来实现依赖于渲染视图的RenderBody()中的上下文依赖菜单?

每个控制器应该处理这个问题,还是应该在其他地方处理?

3 个答案:

答案 0 :(得分:1)

您可以创建特定于控制器的_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>

答案 1 :(得分:0)

您可以使用子操作。这个想法是有这样的控制器动作:

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

答案 2 :(得分:0)

您还可以检查特定ViewData ||的主/共享布局ViewBag值。

@if(ViewData["_ContextMenuList_"] is List<ContextMenuItem>) {
       /// render the rest of the menu directly or in  a strongly typed partial view. 
}

我会使用具有Menu文本,动作,控制器,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; }
}

然后仅在有意义的Controller操作中设置此值,并使用相关的上下文数据填充它。

// 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非常相似。