2012-05-10 27 views
4

我在_Layout.cshtml菜單:如何動態設置樣式列表項中_Layout.cshtml

<td class="MenuStructure"> 
    <ul id="menu"> 
     <li>@Html.ActionLink("First Page", "Page1Action", "Main")</li> 
     <li>@Html.ActionLink("Second Page", "Page2Action", "Main")</li> 
     <li>@Html.ActionLink("Third Page", "Page3Action", "Second")</li> 
    </ul> 
</td> 

當點擊動作鏈接之一,我想設置類<的li>將其包含到「selected」中,並將其他< li>元素的類包含到「」中。

這工作:

<script type="text/javascript"> 
     $(document).ready(function() { 
     var selMenu = '@ViewBag.SelectedMenu'; 
      if (selMenu == "page1") { 
       $("#page1").attr('class', 'selected'); 
       $("#page2").attr('class', ''); 
       $("#page3").attr('class', ''); 
      } 
      if (selMenu == "page2") { 
       $("#page1").attr('class', ''); 
       $("#page2").attr('class', 'selected'); 
       $("#page3").attr('class', ''); 
      } 
     }); 
    </script> 

,但它是非常難看。有人能給我一個更優雅的方式來做到這一點嗎?

回答

2

如果您將點擊事件處理程序添加到a元素組中,則可以輕鬆地將該類添加到單擊元素的li中,並將其移除到所有兄弟,而不管其數量爲多少。這消除了對每個li的if語句和attr更新的需要。

這裏有一個例子:

http://jsfiddle.net/JjBgm/4/

標記:

<ul id="menu"> 
    <li><a href="#">one</a></li> 
    <li><a href="#">two</a></li> 
    <li><a href="#">three</a></li> 
</ul> 

的jQuery:

$(document).ready(function() { 

    $('#menu li a').click(function() { 
     $(this).parent().addClass('selected').siblings().removeClass('selected'); 
    }); 

}); 

你得明顯修改這一方法與MVC您的需求,但這個概念應該可行。

編輯:因爲你提到有一個往返所涉及的上述可能無法正常工作的服務器。在這種情況下,您可以根據所選菜單構建客戶端ID並從那裏控制該類。

$(document).ready(function() { 
    var selMenu = '@ViewBag.SelectedMenu'; 
    $("#" + selMenu).addClass('selected').siblings().removeClass('selected'); 
}); 

這是假設#page1#page2等參考<li>元素,而服務器處理後,看到你的結果標記。

如果#page1<a>標籤,那麼你的聲明將是:

$("#" + selMenu).parent().addClass('selected').siblings().removeClass('selected'); 

未經測試的,當然。主要觀點是動態構建您的選擇器,然後根據需要使用同級和父級選擇器清除類。它更乾淨。

+0

的@ Html.ActionLink導致回發(不知道這是MVC3中的正確術語),所以這是有效的,但僅適用於頁面刷新之前的短暫時刻,並且沒有鏈接再次具有「已選擇」類。 – KennyZ

+0

@KennyZ啊是沒有考慮往返...我會更新 –

+0

謝謝!當我檢查代碼時,我會感覺好多了! – KennyZ

0

我想這是你的網站主導航,和你想保持「選擇」頂部的菜單,即使你是不是確切的動作(例如,鏈接進入名單,但之後你去'編輯'頁面等)。

有兩種方法可以做到這一點。一種方法是在viewbag中放置一個屬性,然後在_layout.cshtml文件中檢查它的呈現時間。

// in controller Action method 
ViewBag.SelectedMenu = "first" 
// in view 
<li class="@((ViewBag.SelectedMenu == "first") ? "selected-class" : "")">first link</li> 

第二種方式(即我們使用)是使用Sitemap包(從安裝的NuGet)。然後,您可以在根目錄中編輯您的站點地圖文件,並將所有鏈接放在那裏(即使您不直接用於導航的鏈接)。然後,你有控制器爲你呈現你的<ul><li>'s。它提供了與現在相同的HTML,很大程度上,所以CSS仍然可以工作。

  • 在一個地方所有的菜單東西
  • 網站地圖尊重[授權]屬性,或其他過濾器,隱藏登錄僅鏈接
  • 可以隱藏/中可能並不存在的菜單顯示節點(重新映射的URL等)
  • 很多其他不錯的小功能

Mvc.sitemap文件:

<mvcSiteMapNode title="Home" controller="Home" action="Index"> 
<mvcSiteMapNode title="Get a car" controller="Cars" action="Buy"/> 
    <mvcSiteMapNode title="Reports" controller="Report" action="AllReports"> 
     <mvcSiteMapNode title="" controller="Report" action="ViewMPG"/> 
    </mvcSiteMapNode> 
</mvcSiteMapNode> 

,然後在你的_Layout.cshtml文件:

<td class="MenuStructure"> 
    <!-- one level menu starting at top (home), including the "home" link --> 
    @Html.MvcSiteMap().Menu(0, true, true, 1) 
</td> 

然後修改Views\Shared\MenuHelperModel.cshtml轉變作風:我li元素內

<ul id="menu"> 
    @foreach (var node in Model.Nodes) 
    { 
     var show = node.IsInCurrentPath && (!node.IsRootNode || node.IsCurrentNode); 
     var cls = show ? "selected" : ""; 
     <li class="@cls">@Html.DisplayFor(m => node)</li> 
    } 
</ul> 
+0

有趣。但是,Sitemap解決方案如何處理在所選li節點上設置類並將其從同級中刪除? – KennyZ

+0

對不起,我忘了一個部分!發佈時間比較晚(對我來說)中國時間。我會添加它。編輯這個模板非常標準,它甚至沒有敲我的大腦。不過,至少ViewBag的想法現在將它變成了選定的答案。最後,我認爲最好是使用站點地圖的方式,而不是嘗試手動確保每個操作(以及錯誤和後期等)都設置了ViewBag屬性。我也是這麼想的,但那是_every_控制器中的一行代碼。 –

相關問題