Tag Helpers 介紹
原文:Introduction to Tag Helpers
作者:Rick Anderson
翻譯:劉浩楊
校對:高嵩(Jack)
- 什么是 Tag Helpers?
- Tag Helpers 提供了什么
- 管理 Tag Helper 范圍
- Tag Helpers 智能感知支持
- Tag Helpers 和 HTML Helpers 比較
- Tag Helpers 和 Web 服務器控件比較
- 自定義 Tag Helper 元素字體
- 附加資源
什么是 Tag Helpers ?
在 Razor 文件中,Tag Helpers 能夠讓服務端代碼參與創建和渲染 HTML 元素。例如,內置的ImageTagHelper能夠在圖像名稱后面追加版本號。每當圖像變化時,服務器為圖像生成一個新的唯一的版本,因此保證客戶端得到當前圖像(而不是舊的緩存圖像)。對於常見任務有許多內置的 Tag Helpers - 比如創建表單,鏈接,加載資產以及更多 - 在公共的 Github 存儲庫中的和以 NuGet 包的方式存在的可用資源。在 C# 里編寫 Tag Helpers,它們的目標是基於元素名稱,特性名稱或者父標簽的 HTML 元素。例如,當 LabelTagHelper
特性被應用時,內置的LabelTagHelper能夠作用於 HTML <label>
元素。如果你熟悉 HTML Helpers,Tag Helpers 在 Razor 視圖中減少 HTML 和 C# 之間的顯示轉換。 Tag Helpers 和 HTML Helpers 比較 解釋了更詳細的差異。
Tag Helpers 提供了什么
一種 HTML-friendly 的開發體驗
在大多數情況下,Razor 標記使用 Tag Helpers 看起來更像標准的 HTML。熟悉 HTML/CSS/JavaScript 的前端設計師在沒有學習 C# Razor 語法的情況下能夠編輯 Razor 。
一個豐富的智能感知環境來創建 HTML 和 Razor 標記
這和 HTML Helpers 有明顯的對比,前一種方法在服務端創建 Razor 視圖中的標記。 Tag Helpers 和 HTML Helpers 比較 講解了更詳細的差異。Tag Helpers 智能感知支持 講解了智能感知環境。
一種使用僅在服務器上可用的信息讓你更高效並且能夠生成更強大,可靠和可維護代碼的方式
例如,在之前當你更改圖像的時候,更新圖像的原則是更改圖像的名稱。出於性能原因應該主動緩存圖像,除非你改變圖像的名稱,你的客戶端有得到一份過期的副本的風險。在之前,一個圖像被編輯后,它的名稱必須改變並且在網絡應用程序中圖像的每一個引用都需要更新。這不僅是體力活,同時也容易出錯(你可能漏掉一個引用,意外的輸入錯誤字符串等)。內置的 ImageTagHelper能夠自動為你做這件事情。ImageTagHelper
能夠在圖像名稱后追加一個版本號,每當圖像變化時,服務器為圖像自動生成一個新的唯一的版本。客戶端被保證得到當前的圖像。通過使用 ImageTagHelper
這種健壯性和節省勞力基本上是無償的。
大多數內置的 Tag Helpers 指向現有的 HTML 元素並且為這些元素提供服務端特性。例如:在Views/Account 文件夾下的許多視圖中使用的 <input>
元素包含了 asp-for
屬性,提取指定模型的屬性名稱到呈現的 HTML 中。Razor 標記如下:
<label asp-for="Email"></label>
生成以下的 HTML :
<label for="Email">Email</label>
asp-for
特性由在 LabelTagHelper
中的 For
屬性提供。查看 :doc:authoring
獲取更多信息。
管理 Tag Helper 范圍
Tag Helpers 的范圍由 @addTagHelper
和 @removeTagHelper
進行控制,並且 "!" 為退出字符。
@addTagHelper
使 Tag Helpers 可用
如果你創建一個新的 ASP.NET Core web 應用,命名為 AuthoringTagHelpers (無身份認證),下面的 *Views/_ViewImports.cshtml* 文件將被添加到你的項目:
@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers // 手動高亮
@addTagHelper
指令使 Tag Helpers 在視圖中可用。在這種情況下,視圖文件是 *Views/_ViewImports.cshtml* ,默認繼承所有的在 Views 和子目錄中的視圖文件;使 Tag Helpers 可用。上面的代碼使用通配符 ("") 來指定在特定程序集(Microsoft.AspNetCore.Mvc.TagHelpers)中的所有的 Tag Helpers 在每一個 Views* 目錄和子目錄中的視圖文件中可用。 @addTagHelper
后面的第一個參數指定要加載的 Tag Helpers (對於所有 Tag Helpers,我們使用 “”),第二個參數 “Microsoft.AspNetCore.Mvc.TagHelpers” 指定包含 Tag Helpers 的程序集。Microsoft.AspNetCore.Mvc.TagHelpers* 是內置的 ASP.NET Core Tag Helpers 程序集。
這個項目中,為了暴露所有的Tag Helpers(創建一個名稱為 AuthoringTagHelpers 的程序集),你可以像下面一樣使用:
@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper "*, AuthoringTagHelpers" // 手動高亮
如果你的項目包含一個使用默認命名空間(AuthoringTagHelpers.TagHelpers.EmailTagHelper
)的 EmailTagHelper
,你可以對 Tag Helper 提供完全限定名(FQN):
@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper "AuthoringTagHelpers.TagHelpers.EmailTagHelper, AuthoringTagHelpers" // 手動高亮
為了使用 FQN 在視圖中添加一個 Tag Helper,你首先添加 FQN (AuthoringTagHelpers.TagHelpers.EmailTagHelper
),然后是程序集名稱(AuthoringTagHelpers)。大多數開發者喜歡使用 "*" 通配符語法。通配符語法允許你在 FQN 中插入通配符 "*" 作為后綴。例如,下列指令將在 EmailTagHelper
中引入:
@addTagHelper "AuthoringTagHelpers.TagHelpers.E*, AuthoringTagHelpers" @addTagHelper "AuthoringTagHelpers.TagHelpers.Email*, AuthoringTagHelpers"
像前面說的,添加 @addTagHelper
指令到 *Views/_ViewImports.cshtml* 文件使 Tag Helper 可用於Views 目錄和子目錄中的所有視圖文件。如果你想選擇在特定的視圖文件中暴露 Tag Helper ,你可以在這些視圖文件中使用 @addTagHelper
指令。
@removeTagHelper
刪除 Tag Helpers
@removeTagHelper
具有和 @addTagHelper
相同的兩個參數,並且它刪除之前添加的一個 Tag Helper 。例如: @removeTagHelper
應用於從特定的視圖中移除特定的 Tag Helper 。在 *Views/Folder/_ViewImports.cshtml* 中使用 @removeTagHelper
刪除 Folder 中所有視圖中特定的 Tag Helper 。
在 *_ViewImports.cshtml* 中控制 Tag Helper 的范圍
你可以在任何視圖文件夾中添加一個 *_ViewImports.cshtml* ,並且視圖引擎添加 *_ViewImports.cshtml* 文件中的指令到包含它們的 *Views/_ViewImports.cshtml* 文件中。如果你為Home 視圖添加一個空 *Views/Home/_ViewImports.cshtml* 文件,它們不會有任何變化因為 *_ViewImports.cshtml* 文件是追加的。你添加到 *Views/Home/_ViewImports.cshtml* 文件(不是默認的 *Views/_ViewImports.cshtml* 文件)的任何 @addTagHelper
指令將會只在 Home 文件夾中公開這些 Tag Helpers 。
禁用個別元素
你可以在元素級別禁用帶有退出符("!")的標簽助手。例如:在 <span>
中帶有退出字符的 Email
驗證被禁用:
<!span asp-validation-for="Email" class="text-danger"></!span>
你必須使用 Tag Helper 退出字符來打開和關閉標簽。(當你添加一個打開標簽時, Visual Studio 編輯器自動添加退出字符來關閉標簽)。在你添加退出字符之后,元素和 Tag Helper 特性將不再以特殊的字體顯示。
使用 @tagHelperPrefix
讓 Tag Helper 用法明確
@tagHelperPrefix
指令允許你指定一個標簽前綴來啟用 Tag Helper 支持和使 Tag Helper 用法明確。在下面的代碼圖片中,Tag Helper 前綴設置為 th:
,因此只有那些使用前綴 th:
的元素支持 Tag Helpers (Tag Helper可用的元素有獨特的字體)。 <label>
和 <input>
元素使用 Tag Helper 前綴並且 Tag Helper 可用, <span>
元素不能使用 Tag Helper。
同一層次的規則適用於 @addTagHelper
也適用於 @tagHelperPrefix
。
Tag Helpers 智能感知支持
當你在 Visual Studio 中創建一個新的 ASP.NET web 應用,在 project.json 文件中添加 "Microsoft.AspNetCore.Razor.Tools" 。這是添加 Tag Helper 工具的包。
考慮寫一個 HTML <label>
元素。在 Visual Studio 編輯器中你一進入 <l
,智能感知顯示匹配的元素:
你得到的不僅僅是 HTML 的幫助,而且圖標(下面含有“<>” 的“@”符號)。
有針對性的通過 Tag Helpers 標識元素。純 HTML 元素(如 fieldset
)顯示 "<>" 圖標。
一個純 HTML <label>
標簽使用棕色字體顯示 HTML 標簽(默認的 Visual Studio 顏色主題),特性使用紅色,特性值使用藍色。
在你輸入 <label
后,智能感知列出可用的 HTML/CSS 特性和 Tag Helper 目標特性:
智能感知語句完成允許你輸入 tab 鍵來完成所選值的語句:
一旦你輸入了一個 Tag Helper 特性,標簽和屬性的字體改變。使用 Visual Studio 默認的 "Blue" 或 "Light" 顏色主題,字體是醒目的紫色。如果你使用 "Dark" 主題,字體是醒目的藍綠色。在這個文檔中的圖片使用的是默認的主題。
你可以在雙引號("")里輸入 Visual Studio 的 CompleteWord 快捷鍵( 默認的 是 Ctrl +spacebar ),你現在在 C# 中,就像你在一個 C# 類中。智能感知顯示頁面模型的所有方法和屬性。方法和屬性能被使用因為屬性類型是 ModelExpression
。在下面的圖片中,我編輯 Register
視圖,所以 RegisterViewModel
是可用的。
智能感知列出模型在頁面上可用的屬性和方法。豐富的智能感知環境幫助你選擇 CSS class:
Tag Helpers 和 HTML Helpers 比較
Tag Helpers 在 Razor 視圖中附加到 HTML 元素,而 `HTML Helpers 在 Razor 視圖中作為穿插到 HTML 的方法被調用。考慮下面的 Razor 標記,它創建一個帶有 "caption" CSS class的HTML label 標簽:
@Html.Label("FirstName", "First Name:", new {@class="caption"})
at (@
) 符號告訴 Razor 這是代碼的開始。接下來的兩個參數("FirstName" 和 "First Name:")是字符串,所以 `IntelliSense 不能幫助。最后的參數:
new {@class="caption"}
是一個用於表示特性的匿名對象。因為 class 是一個 C# 的保留關鍵字,使用 @
符號強制 C# 解釋"@class=" 作為一個符號(屬性名稱)。對於一個前端設計師(一些人熟悉 HTML/CSS/JavaScript 和其他客戶端技術但是不熟悉 C# 和 Razor)來講,該行的大部分是陌生的。整行必須在沒有智能感知的幫助下編寫。
使用 LabelTagHelper
,相同的標記可以被寫為:
使用 Tag Helper 的版本,一旦你在 Visual Studio 編輯器輸入 <l
,智能感知顯示匹配的元素:
智能感知幫助你寫整行代碼。 LabelTagHelper
也默認設置 asp-for
特性值("FirstName")的內容到 "First Name";它轉換駝峰名稱屬性到由每一個首字母大寫的屬性名稱組成的句子。在下面的標記中:
生成:
<label class="caption" for="FirstName">First Name</label>
如果你想添加內容到 <label>
中,camel-cased 到 sentence-cased 的內容不被使用。例如:
生成:
<label class="caption" for="FirstName">Name First</label>
下面的代碼圖片展示了從傳統的包含在 Visual Studio 2015 中的 ASP.NET 4.5.x MVC 的模版生成的Views/Account/Register.cshtml Razor 視圖的表單部分。
Visual Studio 編輯器使用灰色背景顯示 C# 代碼。例如, AntiForgeryToken
HTML Helper:
@Html.AntiForgeryToken()
被灰色背景顯示。在 Register 視圖中大部分標記是 C#。與使用 Tag Helpers 的等效方法比較:
和 HTML Helpers 方法相比,這些標記干凈的多並且更容易閱讀,編輯和維護。C# 代碼減少到服務器需要知道的最小值。 Visual Studio 編輯器通過一個獨特的字體顯示標記的目標。
考慮 Email 組:
<div class="form-group"> <label asp-for="Email" class="col-md-2 control-label"></label> <div class="col-md-10"> <input asp-for="Email" class="form-control" /> <span asp-validation-for="Email" class="text-danger"></span> </div> </div>
每一個 "asp-" 特性都有一個 "Email" 值,但是 "Email" 不是字符串。在這個上下文, "Email" 是對於 RegisterViewModel
的 C# 模型表達式屬性。
使用Tag Helper 注冊表單中的方法,Visual Studio 編輯器會幫助你編寫 所有 標記,而Visual Studio 沒有給 HTML Helpers 方法的代碼提供幫助 IntelliSense support for Tag Helpers
_ 詳細介紹 Tag Helpers 在 Visual Studio 編輯器中的工作。
Tag Helpers 和 Web 服務器控件比較
-
Tag Helpers 不擁有它們所關聯的元素,它們只簡單的參與元素和內容的渲染。ASP.NETWeb Server controls聲明並且在頁面上調用。
-
`Web 服務器控件有一個不一樣的生命周期使得開發和調試困難。
-
Web 服務器控件允許你給通過客戶端控件給客戶端文檔對象模型(ocument Object Model ,DOM)添加功能。Tag Helpers 不具有 DOM。
-
Web 服務器控件包含自動的瀏覽器檢測。 Tag Helpers 不能識別瀏覽器。
-
多個 Tag Helpers 可以作用在相同的元素,而你通常不能構成 Web 服務器控件。
-
Tag Helpers 可以修改在它們范圍內的標簽和 HTML 元素的內容,但是不直接修改頁面上的任何內容。 Web 服務器控件有一個較小的特定范圍,可以執行影響頁面其他部分的操作,從而造成非預期的副作用。
-
Web 服務器控件使用類型轉換器(type converters)轉換字符串到對象。使用 Tag Helpers,你本身就使用 C# 工作,所以你不需要做類型轉換。
-
Web 服務器控件使用 System.ComponentModel實現組件和控件的運行時和設計時行為。
System.ComponentModel
包括用於實現屬性和類型轉換器的基類和接口,綁定到數據源和授權組件。和 Tag Helpers 對比,通常來自TagHelper
,並且TagHelper
基類只公開兩個方法Process
和ProcessAsync
。
自定義 Tag Helper 元素字體
你可以在 工具 > 選項 > 環境 > 字體和顏色 中自定義字體和顏色:
附加資源
- Authoring Tag Helpers
- Working with Forms (Tag Helpers)
- TagHelperSamples on GitHub包含與 Bootstrap一起工作的 Tag Helper 示例。
dotNet Core Studying Group:436035237