ASP.NET MVC Core的TagHelper(基礎篇)


TagHelper又是一個新的名詞,它替代了自之前MVC版本的HtmlHelper,專注於在cshmlt中輔助生成html標記。

通過使用自定義的TagHelper可以提供自定義的Html屬性或元素,借助服務端強大的編程API,使得cshtml的頁面標記功能更加強大。

利用自定義標記賦予元素功能或添加屬性的方式,跟Angular有點類似。

在MVC Core中內置的很多asp-XXX開頭的TagHelper,后續再介紹,這里重點看看如何定義自己的TagHelper。

我們通過定義一個簡單的TagHelper來描述他的基本用法:

項目准備

還是基於ASP.NET MVC Core Starter Kit的項目模板創建一個示例項目,具體怎樣用請參考鏈接中的介紹。

1.這個TagHelper的目的是提供一個設置button樣色的自定義屬性標記,有這個標記的html元素將自動設置對應的css樣式。

<button type="submit" bs-button-color="danger">Add</button>

這里定義的自定義屬性是bs-button-color,我們預期生成的html是

<button type="submit" class="btn btn-danger">Add</button>

接下來創建TagHelper類,新建一個TagHelpers目錄,新建一個ButtonTagHelper類,如下

public class ButtonTagHelper : TagHelper
    {
        public string BsButtonColor { get; set; }

        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            output.Attributes.SetAttribute("class", $"btn btn-{BsButtonColor}");
        }
    }

這個短小的類,根據程序員的思維可以推導出大概的意思

a.BsButtonColor這個屬性匹配的是bs-button-color這個屬性標記,在運行時會將html屬性轉化成C#對象的屬性

b.然后BsButtonColor的值通過html提供,然后在Process中使用

c.Process方法設置目標元素的class

d.其中TagHelperContext和TagHelperOutput提供了適用的API,拯救了程序員,里面的屬性或者方法夠我們改變世界了。

當然這樣做的話,會讓人產生疑問,那豈不是每個元素都要去匹配一下,沒錯這是默認的行為,后面會提到如何縮小查找范圍。

對於這樣的功能,如果使用老版本的HtmlHelper實現,那么會看起來不那么Html,比如上述的功能用HtmlHelper的實現方式類似如下方式

@Html.TextBoxFor(m => m.Population, new { @class = "form-control" } )

那么這個寫法對於前端開發人員就不那么友好了,畢竟別人不同什么是@Html.TextBoxFor,bs-button-color這種方式更加直接,對html的入侵從視覺上來看更加的友好。

2 注冊TagHelper

光定義還不行,還得注冊讓MVC知道這個自定義的TagHelper。

打開_ViewImports.cshtml,改成如下內容

@using CustomTagHelper.Models
@addTagHelper CustomTagHelper.TagHelpers.*, CustomTagHelper

其中第二行尤為重要,其目的是說明將我們定義的TagHelper添加注冊到頁面中,這樣頁面就能識match到。

注冊完之后就能調用使用了,我們把自定義的TagHelper應用到Home/Create.cshtml的Add按鈕

<button type="submit" bs-button-color="danger">Add</button>

運行之后效果,查看html可以得知已經生效

image

3 設置TagHelper的應用范圍

剛才我們提到在匹配TagHelper的時候是使用元素類型去匹配,比如我們這里的ButtonTagHelper,會匹配所有的buttton。但實際上這不是我們需要的,我們只希望出現了自定義html標記屬性的元素才應用這個TagHelper。

MVC Core為我們提供了HtmlTargetElement屬性標記類解決這個問題,讓TagHelper的應用更加的精准。

我們更新ButtonTagHelper,加入HtmlTargetElement屬性

[HtmlTargetElement("button", Attributes = "bs-button-color", ParentTag = "form")]
    public class ButtonTagHelper : TagHelper
    {
        public string BsButtonColor { get; set; }

        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            output.Attributes.SetAttribute("class", $"btn btn-{BsButtonColor}");
        }
    }

看看HtmlTargetElement的定義,也是一目了然

1 第一個參數是tag類型

2 Attributes定義用於選擇匹配應用元素的屬性

3 ParentTag,設置必須是某個html的子元素才設置

當然有了HtmlTargetElement做護航,我們除了可以縮小范圍,當然也可以用它來擴大影響范圍。

比如我們把第一個tag參數去掉,那么就是應用到所有的元素類型(當然也要滿足Attributes和ParentTag條件)

然后把tag參數去掉之后,發現范圍太大不好管控,萬一使用者不知道這范圍定義,那么就會導致樣式錯誤,並且這種bug不好跟,一旦發生也是個坑。

所以既要支持多種tag,又不能污染太多,那么就再apply一個HtmlTargetElement屬性,比如如下

[HtmlTargetElement("button", Attributes = "bs-button-color", ParentTag = "form")]

[HtmlTargetElement("a", Attributes = "bs-button-color", ParentTag = "form")]
    public class ButtonTagHelper : TagHelper
    {
        public string BsButtonColor { get; set; }

        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            output.Attributes.SetAttribute("class", $"btn btn-{BsButtonColor}");
        }
    }

這里用了兩個HtmlTargetElement,指明了只有button和a元素可以應用這個tagHelper,后續哪個人復制粘貼到了其他tag也不會受影響。

示例代碼

https://github.com/shenba2014/AspDotNetCoreMvcExamples/tree/master/CustomTagHelper

先寫到這,下一篇將介紹一些稍微高級一點用法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM