在 ASP.NET Core MVC 中使用 Tag Helpers 有什么好处
What is the advantage of using Tag Helpers in ASP.NET Core MVC
我刚刚看到一篇关于名为 Tag helpers 的新 ASP.NET 核心功能的精彩文章。
从那里,我了解到可以替换以下代码:
@model MyProject.Models.Product
@using (Html.BeginForm())
{
<div>
@Html.LabelFor(m => p.Name, "Name:")
@Html.TextBoxFor(m => p.Name)
</div>
<input type="submit" value="Create" />
}
与:
@model MyProject.Models.Product
@addtaghelper "Microsoft.AspNet.Mvc.TagHelpers"
<form asp-controller="Products" asp-action="Create" method="post">
<div>
<label asp-for="Name">Name:</label>
<input asp-for="Name" />
</div>
<input type="submit" value="Save" />
</form>
有一些新语法,例如 asp-controller
、asp-for
等。但是它有什么作用呢?这种新方法的优势是什么?
到目前为止我看到的最重要的改进是它保证对 HTML 元素的控制。虽然方便,但 MVC 使用的 Html 助手会在您尝试执行它们不是为之构建的事情时产生问题。
在MVC5中使用TextBox可以看到一个简单的例子:
@Html.TextBoxFor(m => p.Name)
生成的 HTML 标记如下所示:
<input class="form-control" id="Name" name="Name" type="text" value="">
漂亮又简单。但是如果你想添加一个占位符属性呢?如果你想使用 bootstrap 的验证状态怎么办?如果您有一些需要自定义属性的第 3 方超酷 javascript 库怎么办? None 这些东西在 MVC5 的 初始版本 中是可能的。 尽管它们最终是以 [= 的形式通过更新添加的28=]html属性。即使现在添加自定义属性充其量也只是笨拙。
@Html.TextBoxFor(m => p.Name,
new {@class="form-control has-error", placeholder="Enter Name",
superCoolFeature="Do something cool"})
虽然您可能会争辩说这仍然是直接 HTML 中更少的代码,但它不再是一个重要的优势。更糟糕的是,该解决方案仍然没有涵盖相当常见的属性中的破折号。如果您需要它们,您会遇到诸如 ActionLink htmlAttributes
之类的解决方法
我已经尝试使用自定义编辑器修复这些缺陷,并尝试构建我自己的 TextBox 控件。很快就很明显,替换包含的 TextBox 模板需要大量工作。更糟糕的是,您的模板必须了解您要添加的任何扩展才能使用它们。
似乎将 Bootstrap 和其他第 3 方工具包含到 MVC 中使得当前设计在扩展 HTML 方面存在问题变得更加明显,需要修复。希望标签助手实现足够完整,以便我们将来可以避免使用它们。
我想到了一些事情:
- 正如@ChrisWalter 指出的那样,这些标签助手为 HTML 标签提供了 Open/Closed 质量。您不仅可以让您为常见的 HTML 模式编写扩展方法,还可以 扩展 一个 HTML 元素。这使您可以为每个组件挑选和混合多个扩展,而不必在它们之间进行选择。
HTML 对于需要将内部 HTML 作为参数提供的元素,助手往往无法很好地工作。他们想出了一个巧妙的模式,所以你可以说:
@using (Html.BeginForm(...)){
{
<input ... />
}
但是 BeginForm()
没有任何东西会强制您将其放在 using
语句中,也没有任何东西可以阻止您使用不正确的 HTML 结构。 (<input>
技术上 isn't allowed 直接位于 <form>
标签内。)
- 这为我们进入 HTML5 的 Web 组件世界提供了一个非常简单的过渡垫脚石。您今天编写的供 jQuery 或 Bootstrap 使用和增强的组件可能在几年后作为 Angular 2 或 Polymer 组件更有意义。使用 HTML 语法可以将 HTML 编写为 Web 组件时您希望它看起来的方式,并自动将其转换为现在(或特定的)必须采用的结构浏览器,稍后)。
更不用说,您的 Web Designers 将有真正的 HTML 标签可以编辑,他们可以识别这些标签以重新设计你的页面。设计师不应该成为编码员,这些敏锐的人足以跟上,研究 HTML5 和 CSS3 规范的移动目标。
接受的答案是正确的,但只是更正。
Html 帮助程序使用下划线覆盖属性中的破折号。例如,如果你想要 html 之类的
我的属性=值
然后你可以使用 html 助手,比如
@Html.TextBoxFor(m=>m.id,
新的 { my_attr = 值 })
然后它会相应地转换。
我知道原来的问题问的是优点,但为了完整起见,我不得不提一个缺点:
启用标签助手后,您无法在标签属性中注入 C# 代码。
即此代码将中断:
<!-- this won't work -->
<input class="@GetMyClass()">
<!-- this won't work too -->
<input type="checkbox" @(condition ? "checked" : "") >
要解决此问题,您可以使用自定义标签助手或完全禁用标签助手,如以下答案所述:
P.S。可以放心忽略我的拙见:标签助手是 "magic"。而"magic"在编程方面总是很糟糕。如果某物看起来像 HTML 标签,走路像标签,叫声也像标签 - 那么它应该是 HTML 标签。不知不觉"oh, it's not *really* a tag"。
我刚刚看到一篇关于名为 Tag helpers 的新 ASP.NET 核心功能的精彩文章。
从那里,我了解到可以替换以下代码:
@model MyProject.Models.Product
@using (Html.BeginForm())
{
<div>
@Html.LabelFor(m => p.Name, "Name:")
@Html.TextBoxFor(m => p.Name)
</div>
<input type="submit" value="Create" />
}
与:
@model MyProject.Models.Product
@addtaghelper "Microsoft.AspNet.Mvc.TagHelpers"
<form asp-controller="Products" asp-action="Create" method="post">
<div>
<label asp-for="Name">Name:</label>
<input asp-for="Name" />
</div>
<input type="submit" value="Save" />
</form>
有一些新语法,例如 asp-controller
、asp-for
等。但是它有什么作用呢?这种新方法的优势是什么?
到目前为止我看到的最重要的改进是它保证对 HTML 元素的控制。虽然方便,但 MVC 使用的 Html 助手会在您尝试执行它们不是为之构建的事情时产生问题。
在MVC5中使用TextBox可以看到一个简单的例子:
@Html.TextBoxFor(m => p.Name)
生成的 HTML 标记如下所示:
<input class="form-control" id="Name" name="Name" type="text" value="">
漂亮又简单。但是如果你想添加一个占位符属性呢?如果你想使用 bootstrap 的验证状态怎么办?如果您有一些需要自定义属性的第 3 方超酷 javascript 库怎么办? None 这些东西在 MVC5 的 初始版本 中是可能的。 尽管它们最终是以 [= 的形式通过更新添加的28=]html属性。即使现在添加自定义属性充其量也只是笨拙。
@Html.TextBoxFor(m => p.Name,
new {@class="form-control has-error", placeholder="Enter Name",
superCoolFeature="Do something cool"})
虽然您可能会争辩说这仍然是直接 HTML 中更少的代码,但它不再是一个重要的优势。更糟糕的是,该解决方案仍然没有涵盖相当常见的属性中的破折号。如果您需要它们,您会遇到诸如 ActionLink htmlAttributes
之类的解决方法我已经尝试使用自定义编辑器修复这些缺陷,并尝试构建我自己的 TextBox 控件。很快就很明显,替换包含的 TextBox 模板需要大量工作。更糟糕的是,您的模板必须了解您要添加的任何扩展才能使用它们。
似乎将 Bootstrap 和其他第 3 方工具包含到 MVC 中使得当前设计在扩展 HTML 方面存在问题变得更加明显,需要修复。希望标签助手实现足够完整,以便我们将来可以避免使用它们。
我想到了一些事情:
- 正如@ChrisWalter 指出的那样,这些标签助手为 HTML 标签提供了 Open/Closed 质量。您不仅可以让您为常见的 HTML 模式编写扩展方法,还可以 扩展 一个 HTML 元素。这使您可以为每个组件挑选和混合多个扩展,而不必在它们之间进行选择。
HTML 对于需要将内部 HTML 作为参数提供的元素,助手往往无法很好地工作。他们想出了一个巧妙的模式,所以你可以说:
@using (Html.BeginForm(...)){ { <input ... /> }
但是
BeginForm()
没有任何东西会强制您将其放在using
语句中,也没有任何东西可以阻止您使用不正确的 HTML 结构。 (<input>
技术上 isn't allowed 直接位于<form>
标签内。)- 这为我们进入 HTML5 的 Web 组件世界提供了一个非常简单的过渡垫脚石。您今天编写的供 jQuery 或 Bootstrap 使用和增强的组件可能在几年后作为 Angular 2 或 Polymer 组件更有意义。使用 HTML 语法可以将 HTML 编写为 Web 组件时您希望它看起来的方式,并自动将其转换为现在(或特定的)必须采用的结构浏览器,稍后)。
更不用说,您的 Web Designers 将有真正的 HTML 标签可以编辑,他们可以识别这些标签以重新设计你的页面。设计师不应该成为编码员,这些敏锐的人足以跟上,研究 HTML5 和 CSS3 规范的移动目标。
接受的答案是正确的,但只是更正。 Html 帮助程序使用下划线覆盖属性中的破折号。例如,如果你想要 html 之类的 我的属性=值 然后你可以使用 html 助手,比如 @Html.TextBoxFor(m=>m.id, 新的 { my_attr = 值 }) 然后它会相应地转换。
我知道原来的问题问的是优点,但为了完整起见,我不得不提一个缺点:
启用标签助手后,您无法在标签属性中注入 C# 代码。
即此代码将中断:
<!-- this won't work -->
<input class="@GetMyClass()">
<!-- this won't work too -->
<input type="checkbox" @(condition ? "checked" : "") >
要解决此问题,您可以使用自定义标签助手或完全禁用标签助手,如以下答案所述:
P.S。可以放心忽略我的拙见:标签助手是 "magic"。而"magic"在编程方面总是很糟糕。如果某物看起来像 HTML 标签,走路像标签,叫声也像标签 - 那么它应该是 HTML 标签。不知不觉"oh, it's not *really* a tag"。