我很难找到任何关于HTML助手如何呈现HTML元素的体面文档。例如,对于Html.TextBoxFor,如何为元素指定CSS类或id?关于HTML助手有什么好的文档吗?我只能在网上找到几个非常具体的例子,而且我觉得MSDN文档相当令人困惑.
发布于 2014-05-01 16:38:56
我假设您与文档的混淆来自于所有泛型类型和表达式的讨论。当您不太熟悉这些概念时,查看一个方法定义可能会让人望而却步。让我们看一看接受TextBoxFor的htmlAttributes的重载
public static MvcHtmlString TextBoxFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
Object htmlAttributes
)<Type>位是泛型,它允许在编译时无法知道的类型仍然在方法或类中使用。泛型是相当高层次的,我不能在这里给出一个很好的解释,但是简单地说,这就像创建一个契约。上面的方法本质上告诉编译器,“嘿,我将使用两种我还不知道的类型,但我将把它们称为TModel和TProperty。所以,无论您在哪里看到它们,只要知道它们的类型,就用正确的类型替换它们。”这给了帮助者一种非常必要的能力,使他们不知道类型.否则,您必须为所使用的每个唯一类型提供一个单独的助手,而且由于它通常处理用户定义的类型,这将是不可能的壮举。就如何使用该方法而言,您可以忽略这些。
对于参数,docs给出了以下描述:
型参数 TModel 中转站转轨转轨型模式的类型。 TProperty 中转站价值的类型。 参数 htmlHelper 直接转轨型: System.Web.Mvc.HtmlHelper型 更主要的是,更好地反映了这一方法扩展的HTML辅助实例。 表达式 直接转轨型: System.Linq.Expressions.Expression>型 用于识别包含要呈现的属性的对象的表示。 htmlAttributes 直接转轨型: System.Object型 将包含HTML属性设置为元素的对象进行再加工、再加工。
“类型参数”是我们前面讨论过的泛型。虽然泛型并不总是正确的,但至少在这种情况下,类型参数是自动传递的,所以您不需要关心这个问题。
第一个实际参数htmlHelper是一个静默参数。HTML助手以及Razor中的所有其他帮助程序都是作为扩展实现的。一个扩展仅仅意味着你要接受一些现有的类型,并向它添加新的方法。为此,您可以实现一个静态类,然后向该类中添加静态方法,将其作为其第一个参数,即您希望以this作为前缀扩展的类型。例如,为了扩展String,我要添加:
public static class MyStringExtensions
{
public static string AwesomeExtensionMethod(this string s)
{
// do something with str
}
}然后允许我执行someString.AwesomeExtensionMethod(),然后将someString传递到第一个参数中,以便使用该方法。HTML帮助程序也是如此。
第二个参数是表达式。理解这些都与理解其他高级概念有关,比如lambdas和委托。我不会在这里详细解释,因为如果你感兴趣的话,网上有很多关于这些话题的信息。简单地说,这个参数是您经常看到的m => m.SomeModelProperty爵士,并让助手知道它应该处理的模型属性。
最后一个参数只是一个对象。它只需要传递它所传递的任何内容,并尝试提取一个键值对的字典,这些关键字值对应用于它将要生成的HTML元素上的属性。现在,这并不意味着您真的可以传递任何东西,有些事情只是不起作用,但是它允许您通过接受object来传递一个匿名对象,这意味着您不必为传递属性而麻烦地创建某个自定义类或类实例。匿名对象的形式如下:
new { [Some Key] = [Some Value] }然后,助手接受这个匿名对象并从它创建一个RouteValueDictionary。诚然,这似乎有点奇怪,但微软实现这一功能的部分原因是为了启用MVC的路由系统,他们只是懒洋洋地使用辅助工具,并且使用了相同的路由系统方法。
无论如何,这就是说,您所需要做的就是指定要在匿名对象中添加/修改的属性,助手将进行调整,例如:
@Html.TextBoxFor(m => m.Foo, new { id = "Bar" })不过有两个注意事项。1)某些保留关键字(如"class“)是不允许的。因此,为了指定也恰好是保留关键字的属性名,您可以在它前面加上@。
@Html.TextBoxFor(m => m.Foo, new { @class = "foo" })2)连字符是不允许的,因此如果需要指定类似于data-*属性的内容,则需要使用下划线代替破折号:
@Html.TextBoxFor(m => m.Foo, new { data_bind = "value: Foo" })RouteValueDictionary将按其应有的方式将其转换为data-bind。
https://stackoverflow.com/questions/23410960
复制相似问题