Лучший способ пометить «текущий» элемент навигации в меню - PullRequest
0 голосов
/ 01 ноября 2011

Например, здесь, в StackOverflow, вы можете выбрать главное меню с параметрами: Вопросы , Теги , Пользователи , Значки, без ответа и Задать вопрос . Когда вы находитесь в одном из этих разделов, он выделяется оранжевым цветом.

Каков наилучший способ добиться этого в ASP.NET MVC?

Пока и в качестве доказательства концепции я сделал этого помощника:

    public static String IsCurrentUrl(this UrlHelper url, String generatedUrl, String output)
    {
        var requestedUrl = url.RequestContext.HttpContext.Request.Url;

        if (generatedUrl.EndsWith("/") && !requestedUrl.AbsolutePath.EndsWith("/"))
            generatedUrl=generatedUrl.Substring(0, generatedUrl.Length - 1);

        if (requestedUrl.AbsolutePath.EndsWith(generatedUrl))
            return output;

        return String.Empty;

    }

Этот метод добавляет выходную строку к элементу, если текущий запрос соответствует этой ссылке. Так что это можно использовать так:

<li>
    <a href="@Url.Action("AboutUs","Home")" @Url.IsCurrentUrl(@Url.Action("AboutUs", "Home"), "class=on")><span class="bullet">About Us</span></a>
 </li>

Первая проблема, я в основном дважды звоню на Url.Action, сначала для атрибута "href", а затем в помощнике, и я думаю, что должен быть лучший способ сделать это. Вторая проблема, это не лучший способ сравнить две ссылки. Я думаю, что мог бы создать новую Html.ActionLink перегрузку, поэтому мне не нужно вызывать Url.Action дважды, но есть ли какой-нибудь встроенный способ сделать это?

Бонус: если я добавлю "class=\"on\"", MVC рендерит class=""on"". Почему?

С уважением.

Ответы [ 4 ]

2 голосов
/ 07 ноября 2011

Для проекта, над которым я работаю, у нас была точно такая же проблема. Как выделить текущую вкладку? Это подход, который был принят в то время:

В режиме просмотра главной страницы:

 <% 
   var requestActionName = 
                         ViewContext.RouteData.Values["action"].ToString();
   var requestControllerName = 
                         ViewContext.RouteData.Values["controller"].ToString();
 %>

 <li class="<%=  requestActionName.Equals("Index",
                   StringComparison.OrdinalIgnoreCase)
                   && requestControllerName.Equals("Home",
                   StringComparison.OrdinalIgnoreCase) ? 
                   "current" : string.Empty %>">
            <%: Html.ActionLink("Home", "Index", "Home") %>
  </li>

В основном происходит то, что мы просто сравниваем строки действия и значения контроллера со значениями, связанными со ссылкой. Если они совпадают, то мы называем это текущей ссылкой, и мы присваиваем «текущий» класс пункту меню.

Пока что это работает, но по мере того, как мы становимся больше по размеру, эта установка начинает становиться довольно большой с большим количеством «или» того или другого. Так что имейте это в виду, если вы решите попробовать это.

Удачи, и надеюсь, что это поможет вам.

1 голос
/ 14 ноября 2012

Другой способ - использовать такой метод расширения (например, Razor и C #):

@Html.MenuItem("MainPage","Index", "Home")

Метод:

 public static MvcHtmlString MenuItem(
            this HtmlHelper htmlHelper,
            string linkText,
            string actionName,
            string controllerName
            )
        {
            string currentAction = htmlHelper.ViewContext.RouteData.GetRequiredString("action");
            string currentController = htmlHelper.ViewContext.RouteData.GetRequiredString("controller");
            if (actionName == currentAction && controllerName == currentController)
            {
                return htmlHelper.ActionLink(
                    linkText,
                    actionName,
                    controllerName,
                    null,
                    new
                        {
                            @class = "current"
                        });
            }
            return htmlHelper.ActionLink(linkText, actionName, controllerName);
        }
1 голос
/ 07 ноября 2011

Сделайте это с помощью CSS.На сервере создайте функцию для определения раздела сайта, который нужно выделить, и выведите его в теге body в виде класса css:

В этой статье это объясняется: http://hicksdesign.co.uk/journal/highlighting-current-page-with-css

0 голосов
/ 01 ноября 2011

Не уверен насчет первого бита, но для бонуса:

\ - это escape-символ в C # (и в большинстве языков, если на то пошло), и он будет интерпретировать следующий символ какстрока, а не оператор C #.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...