zoukankan      html  css  js  c++  java
  • 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

    先写到这,下一篇将介绍一些稍微高级一点用法。

  • 相关阅读:
    P2426 删数
    P2115 [USACO14MAR]破坏Sabotage
    P2679 子串
    P2979 [USACO10JAN]奶酪塔Cheese Towers
    P1114 “非常男女”计划
    P2105 K皇后
    P4053 [JSOI2007]建筑抢修
    P1294 高手去散步
    P4316 绿豆蛙的归宿
    P2253 好一个一中腰鼓!
  • 原文地址:https://www.cnblogs.com/shenba/p/6637259.html
Copyright © 2011-2022 走看看