2009-09-24 7 views
17

चर्चा के लिए आधार के रूप में। मानक एएसपी.नेट एमवीसी वेब प्रोजेक्ट बनाएं।एएसपी.नेट एमवीसी में वर्तमान पृष्ठ को कैसे दिखाना है?

यह मास्टर पृष्ठ में दो मेनू आइटम शामिल होंगे:

<div id="menucontainer"> 
    <ul id="menu"> 
    <li> 
     <%= Html.ActionLink("Home", "Index", "Home")%></li> 
    <li> 
     <%= Html.ActionLink("About", "About", "Home")%></li> 
    </ul> 
</div> 

मैं दृश्य सीएसएस शैली वर्तमान पृष्ठ का संकेत कैसे निर्धारित कर सकते हैं। ,

<%= Html.ActionLink("About", "About", "Home", new {class="current"})%></li> 

और, बेशक जब मुख पृष्ठ पर: उदाहरण के लिए, जब बारे में पेज/नियंत्रक में, मैं अनिवार्य रूप से ऐसा करने के लिए करना चाहते हैं

<%= Html.ActionLink("Home", "Index", "Home", new {class="current"})%></li> 

(एक सीएसएस शैली होने मौजूदा नाम जो मेन्यू में दृश्यमान रूप से इंगित करते हैं कि यह वर्तमान पृष्ठ है।)

मैं मास्टर पेज से मेन्यू डिवीजन को सामग्री स्थान धारक में तोड़ सकता हूं, लेकिन इसका मतलब यह होगा कि मुझे प्रत्येक पृष्ठ पर मेनू रखना होगा ।

कोई विचार, क्या इसका कोई अच्छा समाधान है?

उत्तर

24

सबसे आसान तरीका है के लिए विशेष रूप से है वर्तमान नियंत्रक और ViewContext के RouteData से कार्रवाई पाने के लिए है। कीवर्ड से बचने के लिए हस्ताक्षर में परिवर्तन और @ का उपयोग ध्यान दें।

<% var controller = ViewContext.RouteData.Values["controller"] as string ?? "Home"; 
    var action = ViewContext.RouteData.Values["action"] as string ?? "Index"; 
    var page = (controller + ":" + action).ToLower(); 
%> 

<%= Html.ActionLink("About", "About", "Home", null, 
        new { @class = page == "home:about" ? "current" : "") %> 
<%= Html.ActionLink("Home", "Index", "Home", null, 
        new { @class = page == "home:index" ? "current" : "") %> 

ध्यान दें कि आप इसे एक एचटीएमएलहेपर एक्सटेंशन जैसे कि जॉन के साथ जोड़ सकते हैं और इसे क्लीनर बना सकते हैं।

<%= Html.MenuLink("About", "About", "Home", null, null, "current") %> 

कहाँ MenuActionLink

public static class MenuHelperExtensions 
{ 
    public static string MenuLink(this HtmlHelper helper, 
            string text, 
            string action, 
            string controller, 
            object routeValues, 
            object htmlAttributes, 
            string currentClass) 
    { 
     RouteValueDictionary attributes = new RouteValueDictionary(htmlAttributes); 
     string currentController = helper.ViewContext.RouteData.Values["controller"] as string ?? "home"; 
     string currentAction = helper.ViewContext.RouteData.Values["action"] as string ?? "index"; 
     string page = string.Format("{0}:{1}", currentController, currentAction).ToLower(); 
     string thisPage = string.Format("{0}:{1}", controller, action).ToLower(); 
     attributes["class"] = (page == thisPage) ? currentClass : ""; 
     return helper.ActionLink(text, action, controller, new RouteValueDictionary(routeValues), attributes); 
    } 
} 
+0

कोई अच्छा समाधान नहीं है। एक दृश्य नियंत्रकों और कार्यों के बारे में कुछ नहीं पता होना चाहिए। प्रदर्शित करने के लिए डेटा केवल मॉडल द्वारा आपूर्ति की जानी चाहिए। –

+1

यह यूआरएल प्राप्त करने के लिए केवल एक छोटा सा कट है - आप अनुरोधित यूआरएल का उपयोग करके वही काम कर सकते हैं लेकिन फिर आपको इसे पार्स करना होगा। मैं पैटर्न को तोड़ने के इस तंत्र के साथ संतुष्ट हूं। – tvanfosson

+0

वाक्यविन्यास सही है? मुझे मिलता है "सिस्टम के साथ इंडेक्सिंग [] की अभिव्यक्ति के लिए लागू नहीं कर सकता 'System.Web.Routing।RouteData ' " –

0

यह हो सकता है कि यह 5 वां पैरामीटर है, इसलिए अपने एचटीएमएल विशेषता से पहले एक नल स्लॉट करें। इस पोस्ट में यहाँ इस तरह के रूप में वर्णन है, हालांकि आप 4 तर्क पर कुछ सामान में पारित कर सकते हैं, 5 वीं HTMLattributes

+0

कक्षा के बजाय @class :) –

1

है मैं हाल ही में इस तरह दिखता के लिए एक HTML सहायक द्वारा बनाए:

public static string NavigationLink(this HtmlHelper helper, string path, string text) 
{ 
    string cssClass = String.Empty; 
    if (HttpContext.Current.Request.Path.IndexOf(path) != -1) 
    { 
     cssClass = "class = 'selected'"; 
    } 

    return String.Format(@"<li><a href='{0}' {1}>{2}</a></li>", path, cssClass, text); 
} 

कार्यान्वयन इस तरह दिखता है:

<ul id="Navigation"> 
    <%=Html.NavigationLink("/Path1", "Text1")%> 
    <%=Html.NavigationLink("/Path2", "Text2")%> 
    <%=Html.NavigationLink("/Path3", "Text3")%> 
    <%=Html.NavigationLink("/Path4", "Text4")%> 
    </ul> 
+0

मेरे पास इसके साथ कुछ समस्याएं हैं I सबसे पहले, यह स्ट्रिंग आवरण को संबोधित नहीं करता है और अगर आप यूआरएल में एक अलग आवरण प्रदान करते हैं तो ब्रेक हो जाएगा (याद रखें कि उपयोगकर्ता इन्हें सीधे टाइप कर सकते हैं)। दूसरा, स्थैतिक HttpContext.Current पर निर्भरता के अनुसार यूनिट परीक्षण करना मुश्किल होगा। तीसरा, यदि आप "शीर्ष" स्तर के रूप में कई स्तरों/मेनू के उप-स्तरों से मेल खाते हैं तो यह टूट जाता है। अनुमोदित, मेरे समाधान में तीसरी समस्या भी है, लेकिन चूंकि यह स्ट्रिंग मिलान पर निर्भर नहीं है क्योंकि यह कई स्तरों को समायोजित करने के लिए इसे संशोधित करना कुछ आसान है। – tvanfosson

+0

... मुझे पसंद है, और विचार उधार लिया है - धन्यवाद - दृश्य कोड neater बनाने के लिए इसे एक विस्तार विधि बनाने का विचार। – tvanfosson

+0

प्रतिक्रिया के लिए धन्यवाद! मैं अभी भी इस पर एक नौसिखिया हूं और हमेशा अपने कोड को बेहतर बनाने के तरीकों की तलाश में हूं। – Jon

1

हैं आप टी 4 एमवीसी का उपयोग कर रहे हैं आप इस का उपयोग कर सकते हैं:

 public static HtmlString MenuLink(
     this HtmlHelper helper, 
     string text, 
     IT4MVCActionResult action, 
     object htmlAttributes = null) 
    { 
     var currentController = helper.ViewContext.RouteData.Values["controller"] as string ?? "home"; 
     var currentAction = helper.ViewContext.RouteData.Values["action"] as string ?? "index"; 

     var attributes = new RouteValueDictionary(htmlAttributes); 
     var cssClass = (attributes.ContainsKey("class")) 
          ? attributes["class"] + " " 
          : string.Empty; 

     string selectedClass; 
     if(action.Controller.Equals(currentController, StringComparison.InvariantCultureIgnoreCase) 
     { 
      selectedClass = "selected-parent"; 
      if(action.Action.Equals(currentAction, StringComparison.InvariantCultureIgnoreCase)) 
       selectedClass = "selected"; 
     } 
     cssClass += selectedClass; 

     attributes["class"] = cssClass; 

     return helper.ActionLink(text, (ActionResult)action, attributes); 
    } 
0
<script type="javascript/text"> 
$(document).ready(function() { 

     @if (Request.Url.AbsolutePath.ToLower() == "/") 
     { 
      @Html.Raw("$('.navbar-nav li').eq(0).attr('class','active');") 
     } 

     @if (Request.Url.AbsolutePath.ToLower().Contains("details")) 
     { 
      @Html.Raw("$('.navbar-nav li').eq(1).attr('class','active');") 
     } 

     @if (Request.Url.AbsolutePath.ToLower().Contains("schedule")) 
     { 
      @Html.Raw("$('.navbar-nav li').eq(2).attr('class','active');") 
     } 

    }); 
</script> 

5 मि में एक साथ इस chucked, शायद मैं इसे refactor सकता है, लेकिन आप मूल विचार, इसकी शायद सबसे छोटे साइटों के लिए उपयोगी देना चाहिए।