2013-10-07 2 views
1

В настоящее время у меня есть общий файл, который называется _SubMenu.cshtml, но это необходимо реализовать во всех моих представлениях, которые я считаю громоздкими и, возможно, ненужными (?).Возможно ли иметь контекстно-зависимое меню в макете макета?

Поэтому мне интересно, существует ли такая возможность, как «правильный» способ реализации контекстно-зависимого меню в файле общего макета, который изменяется в зависимости от вашего визуализированного представления в RenderBody()?

Должен ли каждый отдельный контроллер обрабатывать это или это что-то, что нужно обрабатывать в другом месте?

ответ

1

Вы можете создать контроллер конкретного _SubMenu.cshtml следующим образом:

~/Views/Controller1/_SubMenu.cshtml 
~/Views/Controller2/_SubMenu.cshtml 
~/Views/Controller2/_SubMenu.cshtml 

Затем в Layout:

@Html.Partial("_SubMenu") 

The 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> 
+0

Разве это не похоже на то, что я сейчас делаю?Весь смысл для меня состоит в том, чтобы один общий файл макета поддерживал и мог отображать его, когда я хочу, на основе того, какой вид в настоящее время отображается. –

+1

Я обновил свой ответ. – haim770

+0

Спасибо! Вы считаете, что последний подход, который вы добавили в отредактированном сообщении, является плохой практикой, и если да, то почему? :) –

0

Вы можете использовать дочерние действия. Идея заключается в том, чтобы иметь действие контроллера, как это:

public class SomeController: Controller 
{ 
    [ChildActionOnly] 
    public ActionResult SomeAction() 
    { 
     SomeViewModel model = ... 
     return PartialView(model); 
    } 
} 

и тогда вы будете иметь соответствующий частичный вид:

@model MyViewModel 
... 

, которые могут быть включены в макете или вид:

@Html.Action("SomeAction", "SomeController") 

Phil Haack blogged about child action здесь: http://haacked.com/archive/2009/11/17/aspnetmvc2-render-action.aspx

0

Вы также можете иметь мастер/общая проверка макета для конкретного 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; 

Возможно, это утомительно, поскольку вы должны делать это во всех соответствующих действиях на данном контроллере. если это тот рефакторинг, который кодирует в частную функцию внутри контроллера и вызывает его, когда он применяется.

Некоторые люди могут утверждать, что эти данные всегда должны быть в классе модели, в этом случае я считаю это контекстуальными данными и не обязательно частью модели под рукой. Это также упрощает кодирование, просто поместив код визуализации в мастер-класс, который не знает модель. Это очень похоже на _LogOnPartial.cshtml, который находится на некоторых шаблонах MVC.

Смежные вопросы