網站開發一定遇過網頁上有很多選項,這些選項又要用程式去生出來,還要去判斷選項是不是當前頁面來給予不同的CSS,原本的開發方式寫起來會很繁瑣又笨,但是在MVC上卻變得相當精美。
上述的問題以英文簡單來說就是Active Navigation Bar,所以我就用這個來當範例。
Active Navigation Bar
原本的prototype長的這個樣子。
轉成MVC寫法會變成大概這個樣子。
<ul> <li>@Html.ActionLink("Home", "Index", "Home")</li> <li>@Html.ActionLink("FAQ", "FAQ", "Home")</li> <li>@Html.ActionLink("Contact Us", "Contact", "Home")</li> </ul>
東西看起來是好了,但是還要去另外判斷目前的頁面來改CSS實在是很麻煩的一件事,這時候就可以用HtmlHelper Extension來精美的處理掉這件事。
HtmlHelper Extension
我是另外寫了一個叫做ActiveNavigationBar的功能去專門處理Navigation Bar這件事,用TagBuilder跟ActionLink組出我要的東西,然後借用demo小鋪的ASP.NET MVC 如何判斷現在是哪一頁這個功能去判斷使否在那頁,再去增加<li>的class,所以語法如下。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Routing; using System.Web.Mvc; using System.Web.Mvc.Html; namespace TestMVC.Common { public static class Helpers { public static MvcHtmlString ActiveNavigationBar(this HtmlHelper helper, string linkText, string actionName, string controllerName) { if (IsCurrentAction(helper, actionName, controllerName)) { return ListLink(helper, linkText, actionName, controllerName, true); } return ListLink(helper, linkText, actionName, controllerName); } private static MvcHtmlString ListLink(this HtmlHelper helper, string linkText, string actionName, string controllerName, bool active) { var builder = new TagBuilder("li"); if(active) builder.AddCssClass("active"); builder.InnerHtml = helper.ActionLink(linkText, actionName, controllerName).ToHtmlString(); return new MvcHtmlString(builder.ToString()); } private static MvcHtmlString ListLink(this HtmlHelper helper, string linkText, string actionName, string controllerName) { return ListLink(helper, linkText, actionName, controllerName, false); } //from domo public static bool IsCurrentAction(this HtmlHelper helper, string actionName, string controllerName) { string currentControllerName = (string)helper.ViewContext.RouteData.Values["controller"]; string currentActionName = (string)helper.ViewContext.RouteData.Values["action"]; if (currentControllerName.Equals(controllerName, StringComparison.CurrentCultureIgnoreCase) && currentActionName.Equals(actionName, StringComparison.CurrentCultureIgnoreCase)) return true; return false; } } }有點長,我懶得排版了,反正他就會自動判斷要不要加css上去,如果有特例的地方也可以自行加上,我貼上的是沒有特例的版本。
另外我想應該是MVC4的安全性考量(not sure),現在的版本用string輸出HtmlHelper到頁面上,會變成HtmlEncode過的格式,一個解法是在頁面上多做一次處理,另外一個就是改後端輸出了,所以我是寫成輸出為MvcHtmlString,而不是一般大部分人在HtmlHelper Extension寫的輸出為String。
Front-end
於是在頁面上引用這個Extension之後
@using TestMVC.Common;就可以很精美的處理掉繁雜的Active Navigation Bar問題了。
收工!!
No comments:
Post a Comment