入口
任何方法都需要一个入口,这个入口可能是某个静态类,甚至直接定义在global下最直接的“方法”。而ASP.NET MVC视图的辅助方法的入口往往定义在ViewPage中。例如与HTML相关的辅助方法定义在ViewPage.Html属性下,而与URL相关的辅助方法都定义在ViewPage.Url属性下(ViewUserControl和ViewMasterPage情况也一样)。这样的入口区分,其实也是为辅助方法进行了分类,也让用户可以在IDE的帮助下快速定位到所需的辅助方法。在编写一些简单的自定义辅助方法时,我们可以利用C# 3.0的扩展方法特性,将方法定义在HtmlHelper和UrlHelper上,这样便可直接在页面上使用。而对于一些特殊情况,例如目前的状况,我们便需要重新定义一个入口,以便我们的辅助方法可以以此作为基础进行扩展。为此,我们把这一重担交给JQueryHelper类:
public class JQueryHelper
{
public JQueryHelper(ViewContext viewContext, ViewPage page)
: this(viewContext, page, RouteTable.Routes)
{ }
public JQueryHelper(
ViewContext viewContext,
ViewPage page,
RouteCollection routeCollection)
{
this.ViewContext = viewContext;
this.Page = page;
this.RouteCollection = routeCollection;
}
public RouteCollection RouteCollection { get; private set; }
public ViewContext ViewContext { get; private set; }
public ViewPage Page { get; private set; }
}
生成JQueryHelper对象时,我们会保留目前的上下文,让各种扩展方法自行选用。至于保留哪些成员,这并没有太多限制,一般来说够用便可,如有不足,我们按需补充便是。接下来便是要让页面可以访问到这个辅助对象了,与Html和Url这些现有的入口不同,我们使用扩展方法,而不是属性来提供入口。这样做的好处便是在毫无侵入的情况,提供了较为友好的语法,这也是扩展方法的美妙之处:
public static class JQueryExtensions
{
public static JQueryHelper JQuery(this ViewPage page)
{
var key = typeof(JQueryHelper);
var jquery = page.Items[key] as JQueryHelper;
if (jquery == null)
{
page.Items[key] = jquery = new JQueryHelper(page.ViewContext, page);
}
return jquery;
}
}
ViewPage的Items属性是一个页面级别的存储容器,可以使用键/值的方式存放任意数据,我们这里便利用这个特性,为每个页面提供唯一的JQueryHelper对象。