11

HtmlHelperを作成しようとしていますが、ユーザーが独自のカスタム属性をhtmlタグに追加できるようにする必要があります。

TagBuilderクラスを使用してこれを実行しようとしましたが、属性をマージする代わりに、属性を置き換えるだけのようです。

これは私がC#でしたことです:

public static MvcHtmlString List(HtmlHelper helper, object htmlAttributes)
{
    var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

    var tag = new TagBuilder("div");
    tag.AddCssClass("myClass");
    tag.MergeAttributes(attributes, false);

    // tag class property has value "myClass", not "myClass testClass"

    return new MvcHtmlString("<div>");
}

これは私の見解です:

@Html.List(new { @class = "testClass" })

私は何が間違っているのですか?

4

3 に答える 3

32

MergeAttributesはすでにタグにある属性をオーバーライドし、AddCssClassはクラス値に名前を追加します。

したがって、切り替えるだけで機能します。

    tag.MergeAttributes(attributes, false);
    tag.AddCssClass("myClass");

AddCssClassは、その上にマージされたクラス名に追加されます。

于 2012-11-08T11:42:59.623 に答える
17

このTagBuilder.MergeAttributes方法は、期待どおりに機能しません。これは、このメソッドの正確なコードです。

    public void MergeAttributes<TKey, TValue>(IDictionary<TKey, TValue> attributes, bool replaceExisting)
    {
        if (attributes != null)
        {
            foreach (var entry in attributes)
            {
                string key = Convert.ToString(entry.Key, CultureInfo.InvariantCulture);
                string value = Convert.ToString(entry.Value, CultureInfo.InvariantCulture);
                MergeAttribute(key, value, replaceExisting);
            }
        }
    }

    public void MergeAttribute(string key, string value, bool replaceExisting)
    {
        if (String.IsNullOrEmpty(key))
        {
            throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "key");
        }

        if (replaceExisting || !Attributes.ContainsKey(key))
        {
            Attributes[key] = value;
        }
    }

ご覧のとおり、コレクションに新しい属性を追加するだけです(replaceExistingtrueに設定されている場合は、コレクションに既に存在する属性も置き換えられます)。ロジックをマージする値を実行および属性付けしません。値をマージする場合は、自分で行う必要があります。

public static MvcHtmlString List(this HtmlHelperhelper, object htmlAttributes)
{
    var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);        
    if (attributes.ContainsKey("class"))
        attributes["class"] = "myclass " + attributes["class"];
    else
        attributes.Add("class", "myClass");

    var tag = new TagBuilder("div");
    tag.MergeAttributes(attributes, false);

    return new MvcHtmlString(tag.ToString(TagRenderMode.Normal));
}
于 2012-09-28T08:52:27.187 に答える
4

(クラスだけでなく) 他の属性をマージする必要があったため、 AddCssClass() では不十分でした。MergeAttributes が行うべきだと思っていたことを行う拡張メソッドを作成しました。

public static class TagBuilderExtensions
{
    public static void TrueMergeAttributes(this TagBuilder tagBuilder, IDictionary<string, object> attributes)
    {
        foreach (var attribute in attributes)
        {
            string currentValue;
            string newValue = attribute.Value.ToString();

            if (tagBuilder.Attributes.TryGetValue(attribute.Key, out currentValue))
            {
                newValue = currentValue + " " + newValue;
            }

            tagBuilder.Attributes[attribute.Key] = newValue;
        }
    }
}
于 2014-02-05T21:00:18.810 に答える