ASP.NET MVC 5 - Получить текущее имя представления (сторона Razor.cshtml)

Я студент и совершенно новый для ASP.NET MVC, и я пришел из веб-формы ASP.NET. (Используется для него)

У меня есть список:

<ul class="sidebar bg-grayDark">
    <li class="active">
        <a href="@Url.Action("Index", "Home")">
            <span class="mif-home icon"></span>
            <span class="title">Home</span>
        </a>
    </li>
    <li class="bg-hover-black">
        <a href="@Url.Action("Index", "Product")">
            <span class="mif-shop icon"></span>
            <span class="title">Products</span>
            <span class="counter">14</span>
        </a>
    </li>
    <li class="bg-hover-black">
        <a href="@Url.Action("Index", "Category")">
            <span class="mif-flow-cascade icon"></span>
            <span class="title">Categories</span>
            <span class="counter">9</span>
        </a>
    </li>
    <li class="bg-hover-black">
        <a href="@Url.Action("Index", "User")">
            <span class="mif-users icon"></span>
            <span class="title">Users</span>
            <span class="counter">1</span>
        </a>
    </li>
</ul>

Моя цель: По какому виду визуализируется, я хочу добавить "активный" к тому, на который был нажат. Пример: я нажимаю "Категория", затем "Домой" теряет активный класс, а "Категория" добавляет в свой класс. (и наоборот с "bg-hover-black" )

Я думал, что смогу сделать это, проверив визуализацию, но я не знаю, как это сделать. (Я не знаю, как проверить фактический визуализированный вид, но использование Razor для проверки условий в порядке)

Я сначала попытался с JavaScript:   


    $(function () {
        $('.sidebar').on('click', 'li', function () {
            if (!$(this).hasClass('active')) {
                $('.sidebar li').removeClass('active');
                $(this).addClass('active');
            }
        })
    })
    

Но это не работает, потому что когда страница загружается, html повторно отображается с помощью "active" для части Home. (Если я удалю "активный" для дома, то ничего не будет активно onClick, кроме как между загрузкой клика и страницы).

У вас есть решение? Я много искал в Интернете, но ничего не нашел, чтобы помочь мне.

Извините за любые английские ошибки, я все еще изучаю это:).

Спасибо,

Hellcat8.

Ответ 1

Поскольку вы используете соглашение, в котором ваша страница названа в честь контроллера, вы можете сделать это в бритве, чтобы получить имя контроллера/страницы:

@{
 var pageName = ViewContext.RouteData.Values["controller"].ToString()
}

<ul class="sidebar bg-grayDark">
    <li class="@(pageName == "Home" ? "active" : "")">
        <a href="@Url.Action("Index", "Home")">
            <span class="mif-home icon"></span>
            <span class="title">Home</span>
        </a>
    </li>
    <li class="bg-hover-black @(pageName == "Product" ? "active" : "")">
        <a href="@Url.Action("Index", "Product")">
            <span class="mif-shop icon"></span>
            <span class="title">Products</span>
            <span class="counter">14</span>
        </a>
    </li>
    <li class="bg-hover-black @(pageName == "Category" ? "active" : "")">
        <a href="@Url.Action("Index", "Category")">
            <span class="mif-flow-cascade icon"></span>
            <span class="title">Categories</span>
            <span class="counter">9</span>
        </a>
    </li>
    <li class="bg-hover-black @(pageName == "User" ? "active" : "")">
        <a href="@Url.Action("Index", "User")">
            <span class="mif-users icon"></span>
            <span class="title">Users</span>
            <span class="counter">1</span>
        </a>
    </li>
</ul>

Это установит ваш активный класс на стороне сервера страниц, удалив необходимость сделать эту клиентскую сторону с помощью javascript.

Ответ 2

Чтобы подтвердить: вы меняете страницу, когда пользователь нажимает на элемент.

Из-за этого ваш javascript будет запущен, но затем вся страница будет переписана, и вы вернетесь в первое состояние (т.е. с активным домом как в разметке).

Чтобы проверить текущую страницу, вы можете использовать location.href и сравнить ее с URL-адресом href, например:

$(function() {
    $("ul.sidebar>li").removeClass("active");  // or just not have active in the markup
    $("li>a[href=" + location.href + "]").closest("li").addClass("active");
});

В качестве альтернативы, и это было бы более надежным, вы могли бы передать токен (строка, перечисление или константа) с помощью viewmodel и проверить это, например:

<ul class='sidebar'>
    <li data-page='home'...
    ...
    <li data-page='categories'...

затем

$(function() { 
    $("li[[email protected]]").addClass("active")

(или просто в разметке...)

    <li data-page='categories' @(Model.PageName == 'Categories' ? "class=active" : "")>

Ответ 3

Вот мой подход к каскадному раскрывающемуся подменю Bootstrap, украшенному active классами в файле _layout.cshtml проекта Razor Pages.

Основные элементы этого решения:

  • Получите маршрут текущей страницы из ViewContext.RouteData.Values["page"].
  • Используйте помощники тегов @Url.Action() вместо @Url.Action().

Код:

<ul class="nav navbar-nav">
    @{
        String pageRoute = ViewContext.RouteData.Values["page"].ToString();
    }
    <li class="dropdown @( pageRoute.Contains("/CustomerModel/") ? "active" : "" )">
        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Customer-Model <span class="caret"></span></a>
        <ul class="dropdown-menu">
            <li class="@( pageRoute.Contains("/Customers/") ? "active" : "" )"><a asp-page="/CustomerModel/Customers/Index">Customers</a></li>
            <li class="@( pageRoute.Contains("/Partners/")  ? "active" : "" )"><a asp-page="/CustomerModel/CustomerPermissions/Index">CustomerPermissions</a></li>
        </ul>
    </li>
    <li class="dropdown @( pageRoute.Contains("/StaffModel/") ? "active" : "" )">
        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Staff-Model <span class="caret"></span></a>
        <ul class="dropdown-menu">
            <li class="@( pageRoute.Contains("/Staff/")              ? "active" : "" )"><a asp-page="/StaffModel/Staff/Index">Staff</a></li>
            <li class="@( pageRoute.Contains("/StaffGroups/")        ? "active" : "" )"><a asp-page="/StaffModel/StaffGroups/Index">StaffGroups</a></li>
            <li class="@( pageRoute.Contains("/PermissionsGroups/")  ? "active" : "" )"><a asp-page="/StaffModel/PermissionsGroups/Index">PermissionsGroups</a></li>
            <li class="@( pageRoute.Contains("/AllowedModules/")     ? "active" : "" )"><a asp-page="/StaffModel/AllowedModules/Index">AllowedModules</a></li>
            <li class="@( pageRoute.Contains("/AllowedServices/")    ? "active" : "" )"><a asp-page="/StaffModel/AllowedServices/Index">AllowedServices</a></li>
        </ul>
    </li>
</ul>

Ответ 4

Чтобы получить имя активного действия или контроллера, используйте следующее

var controllerName = ViewContext.RouteData.Values["controller"].ToString();
var actionName = ViewContext.RouteData.Values["action"].ToString();

и затем вы можете дать класс для li, используя следующий код:

<li class="@(actionName == "HomePage" ? "active":"")"><a href="~/Account/HomePage">Home</a></li>

или вы можете проверить оба из них следующим образом:

 <li class="@(controllerName =="Account" && actionName == "HomePage" ? "active":"")"><a href="~/Account/HomePage">Home</a></li>