Asp.net core 学习笔记之 Tag Helper

 

refer : 

https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/authoring?view=aspnetcore-5.0

https://visualstudiomagazine.com/articles/2019/05/01/creating-custom-tag-helpers.aspx

tag helper 有点像 angular 的指令.

也适合拿来做一些 ui 组件, 或者是装修一下原生组件. 

从 asp.net core build-in 的 tag helper 可以看出它合适的使用场景. 

 

我们来看看它是怎样 work 起来的. 

首先做一个 class 继续 TagHelper

[HtmlTargetElement("my-email", TagStructure = TagStructure.NormalOrSelfClosing)]
[HtmlTargetElement(Attributes = "[name]=test")]
public class EmailTagHelper : TagHelper
{
    public override void Process(TagHelperContext context, TagHelperOutput output)
    {

    }
}

HtmlTargetElement attribute 是给我们写 selector 的. my-email 是 tag name, TagStucture 是说 tag 的关闭方式, 比如 <div></div> or <dada/> or <input>

多个 HtmlTargetElement 就是可以匹配多种情况, or 的 condition.

Process 方法就是给我们做装修的, 可以添加 attributes, content html, 换 tag 等等

调用

<my-email dada="1234"></my-email>

dada="1234 " 是 angular 的 @Input

在 class 里面加一个 property 就可以了. 默认情况虾 TotalCount 对应的 attribute name 是 total-count (Pascal case to kebab case)

public class EmailTagHelper : TagHelper
{
    [HtmlAttributeName("dada")]
    public int TotalCount { get; set; }
}

来看看 process 

public override void Process(TagHelperContext context, TagHelperOutput output)
{
    output.TagName = "div";
    output.Attributes.SetAttribute("class", "abc xyz");
    output.Content.SetHtmlContent($"<p>Custom Tag {TotalCount}</p>");
}

常用的操作修改 tag, set attribute, set content html 

现在来说说 passing value 沟通, 比如 parent child 沟通, 和当前 global view 沟通等等.

[ViewContext]
[HtmlAttributeNotBound]
public ViewContext ViewContext { get; set; } = null!;

view context 就可以拿到 RouteData, ViewBag, ViewData 等资料

parent child 沟通起来还是比较麻烦的. 

refer : 

https://blog.techdominator.com/article/the-very-basics-of-nesting-for-tag-helpers.html

[HtmlTargetElement("email", TagStructure = TagStructure.NormalOrSelfClosing)]
public class EmailTagHelper : TagHelper
{
    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        context.Items.Add(typeof(EmailContext), new EmailContext());
        var childContent = await output.GetChildContentAsync();
        var emailChildren = ((EmailContext)context.Items[typeof(EmailContext)]).EmailChildren;
        var contentString = childContent.GetContent(); // get content string
    }
}

[HtmlTargetElement("email-child", TagStructure = TagStructure.NormalOrSelfClosing)]
public class EmailChildTagHelper : TagHelper
{
    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        var emailContext = (EmailContext)context.Items[typeof(EmailContext)];
        emailContext.EmailChildren.Add(this);
    }
}

parent 通过 Context.Items 传入一个容器 (也可以传入子层需要的资料), child 把资料放入容器中. 

parent await GetChildContentAsync, 等待子层完成后, 再打开容器, 把子层放进去的资料拿出来. 

这样就可以 parent child 沟通了, 看上去容器时多余的, 子层为什么不能也使用 context.Items.Add 的方式回传给 parent 呢? 

 

因为它是一个 copy... 我也不知道为什么它这样设计啦. 

 

好, 就介绍这么多, 我自己目前够用了. 

 

posted @ 2021-07-13 14:45  兴杰  阅读(226)  评论(0编辑  收藏  举报