寫在開頭
前面介紹了TagHelper的基本概念和內嵌的TagHelpers,想必大家對TagHelper都有一定的了解。TagHelper看上去有點像WebControl,但它不同於WebControl,沒有復雜的生命周期、狀態保持、服務器事件以及較高權限,它只能修改自己Tag的內容。有時覺得它更像angular寫出來的一個widget,有自己特有的Tag,並對其進行解析生成出widget ui和啟動腳本,但是它具有更高的權限,能訪問服務器端信息。
在這章,將要介紹如何自定義TagHelper,考慮到內容比較多,會分成幾個小章節來介紹。
TagHelper基類
通過查看內嵌的TagHelpers的源碼,發現這些TagHelpers都繼承自Microsoft.AspNet.Razor.Runtime.TagHelpers.TagHelper抽象類,而這個類又實現了接口Microsoft.AspNet.Razor.Runtime.TagHelpers.ITagHelper。這個接口是TagHelper最底層的接口,
/// <summary> /// Contract used to filter matching HTML elements. /// </summary> public interface ITagHelper { /// <summary> /// 獲取實現ITagHelper接口的類的解析順序. /// 值小的先用該類來解析。 /// </summary> int Order { get; } /// <summary> /// 根據所給參數context和output異步解析實現ITagHelper的當前類. /// </summary> /// <param name="context">當前HTML Tag的相關信息</param> /// <param name="output">用於生成HTML Tag的HTML元素.</param> /// <returns>用於更新output的Task實例.</returns> Task ProcessAsync(TagHelperContext context, TagHelperOutput output); }
TagHelper類,主要實現了上面接口,添加了一個同步方法來解析當前類,定義如下:
/// <summary> /// Class used to filter matching HTML elements. /// </summary> public abstract class TagHelper : ITagHelper { public virtual int Order { get; } = 0; //同步解析當前TagHelper public virtual void Process(TagHelperContext context, TagHelperOutput output) { } //異步解析當前TagHelper public virtual async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { Process(context, output); } }
一般自定義TagHelper時,只需要設計的類繼承於TagHelper類,重載Process方法,根據context,設置output輸出html元素和腳本即可。
TagHelper類名
自定義的TagHelper類名格式為***TagHelper,其中省略部分***就是該TagHelper應用的Tag。比如我們定義:
public class MyTagHelper: TagHelper { .... }
那么頁面上所有Tag是my都會進入到這個類來解析,注意Tag名要是小寫。
如果***中包括好幾個大寫字母,那么對於的Tag名是將大寫字母變小寫前面加上"-",如果大寫字母在第一個位置,那么只需要改成小寫,前面不需要加“-”。比如
public class MyFirstOneTagHelper: TagHelper { ... }
那么作用的Tag是
<my-first-one ... ></my-first-one>
我們還可以在類上添加TargetElementAttribute來設置作用的Tag,比如定義如下的類時,其作用的Tag名為my。
[TargetElement("my")] public class MyFirstOneTagHelper: TagHelper { ... }
待續...