【问题标题】:Tag Helper - Add all Attributes from a CollectionTag Helper - 添加集合中的所有属性
【发布时间】:2019-12-27 18:00:38
【问题描述】:

我有以下标签助手(这相当于说 Html.Editor):

[HtmlTargetElement("editor", Attributes = "for", TagStructure = TagStructure.WithoutEndTag)]
public class EditorTagHelper : TagHelper {
    private readonly IHtmlHelper _htmlHelper;

    public EditorTagHelper(IHtmlHelper htmlHelper) {
        _htmlHelper = htmlHelper;
    }

    public ModelExpression For { get; set; }

    public IDictionary<string, string> HtmlAttributes { get; set; } = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

    public string TemplateName { get; set; }

    public IDictionary<string, object> ViewData { get; set; } = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);

    [HtmlAttributeNotBound, ViewContext]
    public ViewContext ViewContext { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output) {
        ((IViewContextAware)_htmlHelper).Contextualize(ViewContext);

        ViewData.Add("HtmlAttributes", HtmlAttributes);

        output.Content.SetHtmlContent(_htmlHelper.Editor(For.Name, TemplateName, ViewData));

        output.TagName = null;
    }
}

这样称呼:

<editor for="Name" view-data-test="@("Foo")" html-attributes-class="Bar" />

这是字符串视图模板的代码:

@model string
<input asp-for="@Model" class="form-control" />
@ViewData["Test"]
@(((IDictionary<string, string>)ViewData["HtmlAttributes"])["Class"])

这很好用,但理想情况下,我想将 HtmlAttributes 字典作为属性添加到上面的输入标签助手中。以前我会说以下将属性传递给 HTML 助手:

Html.TextBoxFor(m => m, new { htmlAttributes = ViewData["HtmlAttributes"] })

但是将它们传递给标签助手的等价物是什么?

【问题讨论】:

    标签: c# asp.net-core razor asp.net-core-tag-helpers


    【解决方案1】:

    要创建可以与您的字典一起使用的标签助手,您需要

    • 在标签助手类上提供一个属性,该类采用 HTML 属性字典
    • 解构并循环遍历该字典并将其添加到输出中

    首先将html-attributes 指定为HtmlTargetElement 的逗号分隔属性列表的HTML 属性。

    [HtmlTargetElement("editor", Attributes = "for, html-attributes", TagStructure = TagStructure.WithoutEndTag)]
    public class EditorTagHelper : TagHelper {
    

    然后将它们映射到标签助手本身的属性:

    [HtmlAttributeName("html-attributes")]
    public Dictionary<string, string> HtmlAttributes { get; set; }
    

    在process方法中,通过那个字典解构和foreach

    foreach (var (key, value) in HtmlAttributes)
    {
        output.Attributes.SetAttribute(key, value);
    }
    

    像这样使用它:

    <editor for="Name" view-data-test="@("Foo")" html-attributes="@ViewData["HtmlAttributes"]" />
    

    编辑:

    如果您只想将 ViewData 传递给模板,然后将它们应用到内部的输入元素,您需要按照我告诉您的相同步骤进行操作。但是您跳过将 htmlAttributes 应用到 Editor 元素。

        [HtmlTargetElement("input", Attributes = "for, html-attributes")]
        public class InputTagHelper : TagHelper
        {
            public ModelExpression For { get; set; }
    
            [HtmlAttributeName("html-attributes")]
            public Dictionary<string, string> HtmlAttributes { get; set; }
    
            public override void Process(TagHelperContext context,
                TagHelperOutput output)
            {
                output.TagMode = TagMode.SelfClosing;
                output.Attributes.SetAttribute("name", EditorFor.Name);
                foreach (var (key, value) in HtmlAttributes)
                {
                    output.Attributes.SetAttribute(key, value);
                }
            }
    

    然后在你的模板中,你可以这样做:

    @model string
    <input asp-for="@Model" html-attributes="@((IDictionary<string, string>)ViewData["HtmlAttributes"])" />
    

    【讨论】:

    • 谢谢,但据我所知,这显示了如何设置编辑器标签助手的 HtmlAttributes 属性。但我想从编辑器标签助手的 HtmlAttributes 属性中设置输入标签助手的属性(在字符串编辑器模板内)。
    • 同样的逻辑适用,创建一个新的标签助手,但不是将editor指定为HtmlTargetElement,而是指定input元素。
    • 谢谢,但是这个标签助手相当于 Html.EditorFor。我会更新问题以使这一点更清楚。
    • 你到底在问什么?因为我给你的答案将适用于编辑器以及输入 - 或任何其他元素。
    • 谢谢。我想这个问题更像是一个 Razor 问题,更多的是关于如何将字典中的所有属性添加到标签助手。编辑后的答案可能是解决方案,但这确实意味着我必须为我将 HTML 属性传递给的任何人创建自己的标签助手。
    猜你喜欢
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 2017-11-16
    • 2017-09-14
    • 2016-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多