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... 我也不知道为什么它这样设计啦.
好, 就介绍这么多, 我自己目前够用了.