在标签助手中将数据属性附加到子 DOM 元素上

Append data attributes onto a child DOM element, in a tag helper

我有一个标签助手 styled-checkbox,它包装了一个 <input type="checkbox"> 并添加了其他元素,这样我就可以得到一个自定义样式的复选框。最终呈现的复选框具有此 DOM 结构:

<span>
  <input type="checkbox"...>
  <label..>
  <input type="hidden"..>
</span>

为此,我的 TagHelper 更改了 TagName,然后附加 HTML:

public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
    output.TagName = "span";
    StringBuilder content = new StringBuilder("");
    content.Append($@"<input type=""checkbox"" value=""true"" name=""{Name}"" ... />");
    ... more content Appending here ...

    output.Content.SetHtmlContent(content.ToString());
}

但是,我在使用标签时添加到标签中的任何数据属性都会附加到 span。我希望将它们附加到 input 元素 - 这可能吗?

例如:

<styled-checkbox data-foo="bar"></styled-checkbox>

在该示例中,我希望将 'data-foo' 属性附加到复选框输入 - 但我看不到执行此操作的方法,有可能吗?

您可以使用 TagBuilder 并处理元素的属性。

[HtmlTargetElement("styled-checkbox")]  
    public class MyCustomTagHelper : TagHelper  
    {  
        public string Name { get; set; }  
        public override void Process(TagHelperContext context, TagHelperOutput output)  
        {  
            output.TagName = "span";  
            output.TagMode = TagMode.StartTagAndEndTag;  
            // collect all attributes of styled-checkbox tag
            var attributes = context.AllAttributes.ToDictionary(a => a.Name, a => a.Value.ToString()); 

            var writer = new System.IO.StringWriter();

            CreateInputTagBuilder(attributes).WriteTo(writer, HtmlEncoder.Default);
            CreateHiddenInputTagBuilder().WriteTo(writer, HtmlEncoder.Default);
            // clear attributes of styled-checkbox
            output.Attributes.Clear();
            output.Content.SetHtmlContent(writer.ToString());
        }  
        private TagBuilder CreateInputTagBuilder(Dictionary<string,string> attributes)
        {

            var inputBuilder = new TagBuilder("input");
            inputBuilder.MergeAttributes(attributes);

            // use MergeAttribute instead of Add, Add method throws exception if an attribute exists
            inputBuilder.MergeAttribute("type","checkbox");
            inputBuilder.MergeAttribute("name",this.Name);

            return inputBuilder;
        }
        private TagBuilder CreateHiddenInputTagBuilder()
        {
            var inputBuilder = new TagBuilder("input");
            inputBuilder.Attributes.Add("type","hidden");
            return inputBuilder;
        }
    }

cshtml:

<styled-checkbox data-foo="bar" value="33" name="saeed"></styled-checkbox>

输出:

<span>
    <input data-foo="bar" name="saeed" type="checkbox" value="33">
    <input type="hidden">
</span>