MVC에서 부트 스트랩 탐색 모음에 “active”클래스를 추가하려고하는데 다음과 같이 작성하면 다음과 같이 활성 클래스가 표시되지 않습니다.
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home", null, new {@class="active"})</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
이것은 올바른 형식의 클래스처럼 보이지만 작동하지 않습니다.
<a class="active" href="/">Home</a>
부트 스트랩 문서에서 탐색 표시 줄에 ‘a’태그를 사용해서는 안된다고 명시되어 있지만 위의 방법은 Html.ActionLink에 클래스를 추가하는 올바른 방법이라고 생각합니다. 내가 이것을 할 수있는 또 다른 (정확한) 방법이 있습니까?
답변
부트 스트랩에서 active
클래스는 <li>
요소가 아닌 요소에 적용되어야 합니다 <a>
. 여기에서 첫 번째 예를 참조 하십시오 : http://getbootstrap.com/components/#navbar
활성화 여부에 따라 UI 스타일을 처리하는 방법은 ASP.NET MVC의 ActionLink
도우미 와 관련이 없습니다 . 이것이 Bootstrap 프레임 워크가 구축 된 방식을 따르는 적절한 솔루션입니다.
<ul class="nav navbar-nav">
<li class="active">@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
편집하다:
메뉴를 여러 페이지에서 재사용 할 가능성이 높으므로 메뉴를 여러 번 복사하여 수동으로 수행하지 않고 현재 페이지를 기준으로 선택한 클래스를 자동으로 적용하는 방법이 현명합니다.
가장 쉬운 방법은에 포함 된 값 ViewContext.RouteData
, 즉 Action
and Controller
값을 사용하는 것입니다. 우리는 현재 다음과 같은 것을 사용하여 만들 수 있습니다.
<ul class="nav navbar-nav">
<li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Index" ? "active" : "")">@Html.ActionLink("Home", "Index", "Home")</li>
<li class="@(ViewContext.RouteData.Values["Action"].ToString() == "About" ? "active" : "")">@Html.ActionLink("About", "About", "Home")</li>
<li class="@(ViewContext.RouteData.Values["Action"].ToString() == "Contact" ? "active" : "")">@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
코드가 좋지는 않지만 작업을 완료하고 원하는 경우 메뉴를 부분보기로 추출 할 수 있습니다. 훨씬 더 깔끔한 방법으로이 작업을 수행 할 수있는 방법이 있지만 시작하기 때문에 그대로 두겠습니다. 행운을 빕니다 ASP.NET MVC를 배우십시오!
늦은 편집 :
이 질문은 약간의 트래픽이 발생하는 것으로 보이므로 HtmlHelper
확장 프로그램을 사용하여보다 우아한 솔루션을 사용하는 것으로 나타났습니다 .
편집 03-24-2015 : 선택한 동작을 트리거하는 여러 동작 및 컨트롤러를 허용하고 자식 동작 부분보기에서 메소드를 호출 할 때 처리 할 수 있도록이 방법을 다시 작성해야했습니다. 업데이트를 공유 할 것이라고 생각했습니다!
public static string IsSelected(this HtmlHelper html, string controllers = "", string actions = "", string cssClass = "selected")
{
ViewContext viewContext = html.ViewContext;
bool isChildAction = viewContext.Controller.ControllerContext.IsChildAction;
if (isChildAction)
viewContext = html.ViewContext.ParentActionViewContext;
RouteValueDictionary routeValues = viewContext.RouteData.Values;
string currentAction = routeValues["action"].ToString();
string currentController = routeValues["controller"].ToString();
if (String.IsNullOrEmpty(actions))
actions = currentAction;
if (String.IsNullOrEmpty(controllers))
controllers = currentController;
string[] acceptedActions = actions.Trim().Split(',').Distinct().ToArray();
string[] acceptedControllers = controllers.Trim().Split(',').Distinct().ToArray();
return acceptedActions.Contains(currentAction) && acceptedControllers.Contains(currentController) ?
cssClass : String.Empty;
}
.NET Core와 호환
public static string IsSelected(this IHtmlHelper htmlHelper, string controllers, string actions, string cssClass = "selected")
{
string currentAction = htmlHelper.ViewContext.RouteData.Values["action"] as string;
string currentController = htmlHelper.ViewContext.RouteData.Values["controller"] as string;
IEnumerable<string> acceptedActions = (actions ?? currentAction).Split(',');
IEnumerable<string> acceptedControllers = (controllers ?? currentController).Split(',');
return acceptedActions.Contains(currentAction) && acceptedControllers.Contains(currentController) ?
cssClass : String.Empty;
}
샘플 사용법 :
<ul>
<li class="@Html.IsSelected(actions: "Home", controllers: "Default")">
<a href="@Url.Action("Home", "Default")">Home</a>
</li>
<li class="@Html.IsSelected(actions: "List,Detail", controllers: "Default")">
<a href="@Url.Action("List", "Default")">List</a>
</li>
</ul>
답변
신장:
public static MvcHtmlString LiActionLink(this HtmlHelper html, string text, string action, string controller)
{
var context = html.ViewContext;
if (context.Controller.ControllerContext.IsChildAction)
context = html.ViewContext.ParentActionViewContext;
var routeValues = context.RouteData.Values;
var currentAction = routeValues["action"].ToString();
var currentController = routeValues["controller"].ToString();
var str = String.Format("<li role=\"presentation\"{0}>{1}</li>",
currentAction.Equals(action, StringComparison.InvariantCulture) &&
currentController.Equals(controller, StringComparison.InvariantCulture) ?
" class=\"active\"" :
String.Empty, html.ActionLink(text, action, controller).ToHtmlString()
);
return new MvcHtmlString(str);
}
용법:
<ul class="nav navbar-nav">
@Html.LiActionLink("About", "About", "Home")
@Html.LiActionLink("Contact", "Contact", "Home")
</ul>
답변
asp.net mvc에 view bag 매개 변수를 추가 하여이 작업을 수행했습니다. 여기서 내가 한 일
ViewBag.Current = "Scheduler";
각 페이지에 유사한 매개 변수 추가
레이아웃 페이지에서
<ul class="nav navbar-nav">
<li class="@(ViewBag.Current == "Scheduler" ? "active" : "") "><a href="@Url.Action("Index","Scheduler")" target="_self">Scheduler</a></li>
</ul>
이것은 내 문제를 해결했습니다.
답변
조금 늦을 수 있습니다. 그러나 이것이 도움이되기를 바랍니다.
public static class Utilities
{
public static string IsActive(this HtmlHelper html,
string control,
string action)
{
var routeData = html.ViewContext.RouteData;
var routeAction = (string)routeData.Values["action"];
var routeControl = (string)routeData.Values["controller"];
// both must match
var returnActive = control == routeControl &&
action == routeAction;
return returnActive ? "active" : "";
}
}
그리고 다음과 같이 사용법 :
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class='@Html.IsActive("Home", "Index")'>
@Html.ActionLink("Home", "Index", "Home")
</li>
<li class='@Html.IsActive("Home", "About")'>
@Html.ActionLink("About", "About", "Home")
</li>
<li class='@Html.IsActive("Home", "Contact")'>
@Html.ActionLink("Contact", "Contact", "Home")
</li>
</ul>
</div>
http://www.codingeverything.com/2014/05/mvcbootstrapactivenavbar.html 에서 참조하십시오.
답변
이 질문이 오래되었다는 것을 알고 있지만 여기에 내 목소리를 추가하고 싶습니다. 링크가보기의 컨트롤러에 대해 활성화되어 있는지 여부를 아는 것이 좋습니다.
컨트롤러 동작의 각 뷰에 대해 고유 한 값을 설정하려고합니다. 예를 들어 홈페이지 링크를 활성화하려면 다음과 같이하십시오.
public ActionResult Index()
{
ViewBag.Title = "Home";
ViewBag.Home = "class = active";
return View();
}
그런 다음 내 견해로는 다음과 같이 작성합니다.
<li @ViewBag.Home>@Html.ActionLink("Home", "Index", "Home", null, new { title = "Go home" })</li>
다른 페이지로 이동하면 프로그램, ViewBag.Home이 존재하지 않습니다 (ViewBag.Programs 대신)가 있습니다. 따라서 class = “”도 렌더링되지 않습니다. 나는 이것이 유지 보수성과 청결 모두에서 더 깨끗하다고 생각합니다. 나는 항상 가능한 한 논리를 시야에서 벗어나고 싶어합니다.
답변
Damith 게시 무엇을 고려, 나는 당신이 단지에 의해 활성받을 수 있다고 생각하기 좋아 Viewbag.Title (가장 좋은 방법은 당신의 있도록 콘텐츠 페이지에이를 채우는 것입니다 _Layout.cshtml
페이지가 링크 막대를 잡고). 하위 메뉴 항목을 사용하는 경우 에도 잘 작동합니다.
<li class="has-sub @(ViewBag.Title == "Dashboard 1" || ViewBag.Title == "Dashboard 2" ? "active" : "" )">
<a href="javascript:;">
<b class="caret"></b>
<i class="fa fa-th-large"></i>
<span>Dashboard</span>
</a>
<ul class="sub-menu">
<li class="@(ViewBag.Title == "Dashboard 1" ? "active" : "")"><a href="index.html">Dashboard v1</a></li>
<li class="@(ViewBag.Title == "Dashboard 2" ? "active" : "")"><a href="index_v2.html">Dashboard v2</a></li>
</ul>
</li>
답변
나는 dom의 “예쁘지 않은”답변을 수정 하고 더 추악하게 만들었습니다. 때로는 두 컨트롤러가 충돌하는 동작 이름 (예 : 색인)을 가지므로 다음과 같이하십시오.
<ul class="nav navbar-nav">
<li class="@(ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString() == "HomeIndex" ? "active" : "")">@Html.ActionLink("Home", "Index", "Home")</li>
<li class="@(ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString() == "AboutIndex" ? "active" : "")">@Html.ActionLink("About", "Index", "About")</li>
<li class="@(ViewContext.RouteData.Values["Controller"].ToString() + ViewContext.RouteData.Values["Action"].ToString() == "ContactHome" ? "active" : "")">@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>