HTML帮助程序教程/文档

时间:2014-05-01 15:33:13

标签: asp.net-mvc html-helper

我无法找到有关HTML帮助程序如何呈现HTML元素的任何体面文档。例如,使用Html.TextBoxFor,如何为元素指定CSS类或id?有没有关于HTML助手的好文档?我只能在网上找到一些非常具体的例子,我发现MSDN文档相当令人困惑......

1 个答案:

答案 0 :(得分:2)

我假设你对文档的困惑扩展了所有通用类型和表达式的讨论。当您对这些概念不太熟悉时,查看方法定义可能会非常困难。我们来看看接受TextBoxFor的{​​{1}}的重载:

htmlAttributes

public static MvcHtmlString TextBoxFor<TModel, TProperty>( this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Object htmlAttributes ) 位是泛型,它允许在编译时无法知道的类型仍然在方法或类中使用。泛型是相当高级的,我不能在这里给出一个很好的解释,但简单来说,这就像创建一个契约。上面的方法基本上告诉编译器,“嘿,我将使用我还不知道的两种类型,但我会称它们为<Type>TModel。所以,无论你在哪里看到它们,只要一旦知道就用正确的类型替换它们。“这为助手提供了与类型无关的非常必要的能力。否则,您必须为所使用的每个唯一类型都有一个单独的帮助程序,并且由于它最常处理用户定义的类型,这将是一个不可能的壮举。出于如何使用该方法的目的,您可以忽略这些。

对于参数,文档给出以下描述:

  

类型参数

     

的TModel
  模型的类型。

     

TProperty
  值的类型。

     

<强>参数

     

的HtmlHelper
  键入:System.Web.Mvc.HtmlHelper
  此方法扩展的HTML帮助程序实例。

     

表达
  键入:System.Linq.Expressions.Expression&gt;
  一个表达式,用于标识包含要呈现的属性的对象。

     

htmlAttributes
  键入:System.Object
  包含要为元素设置的HTML属性的对象。

“类型参数”是我们之前谈到的泛型。虽然对于泛型来说并非如此,在这种情况下,至少,类型参数会自动传递,因此您无需关注它。

第一个实际参数TProperty是一个静默参数。 HTML帮助程序以及Razor中的所有其他帮助程序都实现为扩展。扩展只是意味着您正在使用一些现有类型并为其添加新方法。您可以通过实现静态类然后向该类添加静态方法来实现此操作,将其作为第一个参数,即要扩展为htmlHelper的类型。例如,要扩展this,我会添加:

String

然后允许我执行public static class MyStringExtensions { public static string AwesomeExtensionMethod(this string s) { // do something with str } } ,然后将someString.AwesomeExtensionMethod()传递给要使用的方法的第一个参数。 HTML帮助程序也在发生同样的事情。

第二个参数是表达式。理解这些与理解lambda和委托等其他高级概念有关。我不会在这里进行完整的解释,因为如果您有兴趣,可以在线获得有关这些主题的大量信息。简单地说,这个参数是你总是看到的someString爵士乐,并让帮助者知道它应该使用什么模型属性。

最后一个参数只是一个对象。它将简单地接受它传递的任何内容并尝试提取适用于它将要生成的HTML元素的属性的键值对字典。现在,这并不意味着你可以真正传递任何东西,有些东西不会起作用,但它允许你通过接受m => m.SomeModelProperty做的事情允许你传递一个匿名对象,这意味着您不必为了传递属性而烦恼创建一个类的自定义类或实例。匿名对象采用以下形式:

object

然后帮助程序获取此匿名对象并从中创建new { [Some Key] = [Some Value] } 。诚然,这似乎有点奇怪,但是微软实现了这个功能,部分原因是为了启用MVC的路由系统,他们只是对帮助者很懒惰,并且使用了相同的路由系统方法。

无论如何,所有这一切都是说你需要做的就是在你的匿名对象中指定你想要添加/修改的属性,帮助者将进行调整,例如:

RouteValueDictionary

但有两点需要注意。 1)不允许使用某些保留关键字,如“class”。因此,为了指定也恰好是保留关键字的属性名称,请在其前面添加@Html.TextBoxFor(m => m.Foo, new { id = "Bar" })

@

2)不允许使用连字符,因此如果您需要指定类似@Html.TextBoxFor(m => m.Foo, new { @class = "foo" }) 属性的内容,则需要使用下划线代替短划线:

data-*

@Html.TextBoxFor(m => m.Foo, new { data_bind = "value: Foo" }) 会将此值转换为RouteValueDictionary