【问题标题】:Merging attributes合并属性
【发布时间】:2016-03-21 15:06:03
【问题描述】:
public static IHtmlString CheckBoxWithLabelFor<TModel, TProperty>(this HtmlHelper<TModel> helper,
            Expression<Func<TModel, TProperty>> expression, string labelText, object htmlAttributes)
        {

            var metadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
            object currentValue = metadata.Model;
            string property = ExpressionHelper.GetExpressionText(expression);

            var checkBox = new TagBuilder("input");
            checkBox.AddCssClass("checkBoxWithLabel");
            checkBox.GenerateId(property);
            checkBox.Attributes["type"] = "checkbox";
            checkBox.Attributes["name"] = property;
            checkBox.Attributes["value"] = "true";
            checkBox.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes),false);/*added false*/



            var hidden = new TagBuilder("input");
            hidden.Attributes["type"] = "hidden";
            hidden.Attributes["name"] = property;
            hidden.Attributes["value"] = "false";

            if (Equals(currentValue, true))
            {
                checkBox.Attributes["checked"] = "checked";
            }

            var label = new TagBuilder("label");
            label.AddCssClass("checkBoxLabel");

            var htmlText = label.ToString().Replace("</label>", "");
            htmlText += checkBox.ToString(TagRenderMode.SelfClosing);
            htmlText += hidden.ToString(TagRenderMode.SelfClosing);
            htmlText += labelText + "</label>";
            return new HtmlString(htmlText);

AnonymousObjectToHtmlAttributes(htmlAttributes) 仅将“_”替换为“-”。而 MergeAttributes 需要一个键/值类型,因此忽略现有值。无法将对象 HtmlAttributes 更改/转换为具有 IEnumerable、IDictionary 等的字典。我认为 MergeAttributes 应该在循环中提取键/值,但不确定是什么开始滚动?

我希望类具有初始 htmlAttributes 值“editableInNew editableInUpdate readonly”元素以及使用 .AddCssClass 添加的“checkBoxWithLabel”,但无法使其正常工作,我很难过。

【问题讨论】:

  • 是的,该回家了
  • 是的,是时候回家了,肯定是 mecek...@Html.CheckBoxWithLabelFor(x =&gt; x.Tra..., "Yes", new { @readonly="", @class = "editableInNew editableInUpdate readonly" }) 将鼠标悬停在 htmlAttributes 上会得到 { readonly="", class="editableInNew editableInUpdate readonly"} 我有标准复选框,其中包含在该工作中传递的属性,并且几乎完全相同,即 @Html.CheckBoxFor(x =&gt; x.ThirdParty.IsCompany, new { @class = "editableInUpdate editableInNew readonly" })

标签: c# html asp.net-mvc html-helper


【解决方案1】:

您不应尝试在帮助程序中手动生成 html,而应使用内置方法。您不仅编写了更多必要的代码,而且您没有考虑到标准 HtmlHelper 功能,例如绑定到ModelState、客户端验证等,我假设您不知道这些功能。如果您确实想手动执行此操作,我建议您先学习source code

您还应该更改助手的签名以仅允许 boolean 属性。

public static IHtmlString CheckBoxWithLabelFor<TModel>(this HtmlHelper<TModel> helper,
    Expression<Func<TModel, bool>> expression, string labelText, object htmlAttributes)
{
    IDictionary<string, object> attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
    // add the "checkBoxWithLabel" class
    if (attributes.ContainsKey("class"))
    {
        attributes["class"] = "checkBoxWithLabel " + attributes["class"];
    }
    else
    {
        attributes.Add("class", "checkBoxWithLabel");
    }
    // build the html
    StringBuilder html = new StringBuilder();
    html.Append(helper.CheckBoxFor(expression, attributes));
    html.Append(helper.LabelFor(expression, labelText, new { @class = "checkBoxLabel" }));
    // suggest also adding the validation message placeholder
    html.Append(helper.ValidationMessageFor(expression));
    return MvcHtmlString.Create(html.ToString());
}

【讨论】:

  • 优秀的答案 @Stephen Muecke,感谢您对我的坚持,非常感谢。虽然我没有完全遵循逻辑,但您的回答非常有效,谢谢。
  • 我从同事的代码中继承了更复杂的原始版本,但我想进一步阅读并保持简单。再次感谢
  • 哪部分逻辑你不明白?
  • 我猜它的初始定义...public static IHtmlString CheckBoxWithLabelFor&lt;TModel&gt;(this HtmlHelper&lt;TModel&gt; helper, Expression&lt;Func&lt;TModel, bool&gt;&gt; expression, string labelText, object htmlAttributes) {我承认泛型对我来说有点薄弱
猜你喜欢
  • 1970-01-01
  • 2020-05-14
  • 2013-06-12
  • 1970-01-01
  • 2020-08-21
  • 2021-06-17
  • 1970-01-01
  • 2018-04-18
  • 1970-01-01
相关资源
最近更新 更多