MVC 3:使用HtmlHelpers有条件地添加禁用属性

mus*_*fan 69 asp.net-mvc html-helper asp.net-mvc-3

我有一个ASP.Net MVC 3 Web应用程序,我正在使用HtmlHelper类向视图页面添加一个复选框,就像这样......

@Html.CheckBox("CheckBox1", true, new { @class = "Class1" })
Run Code Online (Sandbox Code Playgroud)

我想要做的是根据视图状态属性有条件地添加disabled属性.基本上以下是理想的......

@Html.CheckBox("CheckBox1", true, new { @class = "Class1", @disabled = Model.ReadOnly })
Run Code Online (Sandbox Code Playgroud)

遗憾的是,由于disabled属性的性质,这将不起作用,因为分配给disabled属性的任何值(甚至"false")都将转换为true.

我已经想到了一些解决这个问题的解决方案,所以问题不是我怎么能这样做.但是,有一种简单的方法,如上面所需的方法?或者我是否必须诉诸以下其中一项?

我知道我能做什么......

  1. 创建一个if/else语句并写入不同的Html.CheckBox行(对于可读性而言不是很好 - 并且可能会抛出标记警告 - 不确定)

  2. 跳过HtmlHelper类并手写标记以允许更好的条件属性(保持代码更短,但增加了不一致性)

  3. 创建一个自定义帮助程序,它采用"禁用"参数(最干净的解决方案,但需要不需要的额外方法 - 可能是目前为止最好的选择)

Big*_*ike 50

在视图/帮助器中的某个位置定义它

@functions {
 object getHtmlAttributes (bool ReadOnly, string CssClass) 
 {
     if (ReadOnly) {
         return new { @class = CssClass, @readonly = "readonly" };
     }
     return new { @class = CssClass };
 }
}
Run Code Online (Sandbox Code Playgroud)

然后使用:

@Html.TextBox("name", "value", @getHtmlAttributes(Model.ReadOnly, "test"))
Run Code Online (Sandbox Code Playgroud)

  • 嗯..当我将它与 .TextBoxFor() (而不是 .TextBox() )一起使用时,上面的示例不起作用 - 匿名类型投影初始值设定项应该是简单的名称或成员访问表达式... (2认同)

Mir*_*Mir 32

以下是我对这个类似问题的回答:https://stackoverflow.com/a/13922813/495000


我创建了以下Helper - 它需要一个布尔值和一个匿名对象.如果disabled为true,则将disabled属性添加到匿名对象(实际上是Dictionary),其值为"disabled",否则根本不添加该属性.

public static RouteValueDictionary ConditionalDisable(
   bool disabled, 
   object htmlAttributes = null)
{
   var dictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

   if (disabled)
      dictionary.Add("disabled", "disabled");

   return dictionary;
}
Run Code Online (Sandbox Code Playgroud)

它的一个例子:

@Html.TextBoxFor(m => m.SomeProperty,    
   HtmlHelpers.ConditionalDisable(true, new { @class = "someClass"))
Run Code Online (Sandbox Code Playgroud)

这种方法的一个巨大优势在于它几乎适用于所有MVC HtmlHelper,因为它们都具有接受RouteValueDictionary而不是匿名对象的Overload.

注意事项:
HtmlHelper.AnonymousObjectToHtmlAttributes()使用一些花哨的代码忍者工作来完成工作.我不完全确定它的性能如何......但它足以满足我的需求.你的旅费可能会改变.

我不是特别喜欢它的名字 - 但我无法想出更好的东西.重命名很容易.

我也不喜欢使用语法 - 但我又无法想出更好的东西.改变应该不难.对象的扩展方法是一个想法...你最终会得到new { @class = "someClass" }.ConditionalDisable(true)但是如果你只想要禁用属性并且没有任何额外的东西来添加你最终会得到一些粗略的东西new {}.ConditionalDisable(true);,你最终会得到一个扩展显示所有的方法object......这可能是不可取的.


And*_*uhl 11

如果你想要更简洁的语法而不需要辅助函数,你可以在定义用于@HTML.Checkbox助手的html属性的字典时使用三元语句...

@Html.CheckBox("CheckBox1", true, Model.ReadOnly 
       ? new { @class = "Class1", @disabled = Model.ReadOnly } 
       : null)
Run Code Online (Sandbox Code Playgroud)

在这种情况下,Model.ReadOnly为false,null作为html属性的字典传递.

  • 如果要设置其他属性,这可能会非常冗长. (7认同)
  • 如果您仍想在 false 条件下设置 @class 属性,这将不起作用。 (2认同)

RAM*_*RAM 5

您认为我的简单解决方案怎么样?它可以轻松地与两种可能的HtmlAttributes类型一起使用:

  • Dictionary<string, object>
  • Anonymous Object

首先将以下简单内容添加extension class到您的项目中:

public static class HtmlAttributesExtensions
{
    public static IDictionary<string, object> AddHtmlAttrItem(this object obj, string name, object value, bool condition)
    {
        var items= !condition ? new RouteValueDictionary(obj) : new RouteValueDictionary(obj) {{name, value}};
        return UnderlineToDashInDictionaryKeys(items);
    }
    public static IDictionary<string, object> AddHtmlAttrItem(this IDictionary<string, object> dictSource, string name, object value, bool condition)
    {
        if (!condition)
            return dictSource;

        dictSource.Add(name, value);
        return UnderlineToDashInDictionaryKeys(dictSource);
    }
    private static IDictionary<string, object> UnderlineToDashInDictionaryKeys(IDictionary<string,object> items)
    {
        var newItems = new RouteValueDictionary();
        foreach (var item in items)
        {
            newItems.Add(item.Key.Replace("_", "-"), item.Value);
        }
        return newItems;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在可见:

示例1 HtmlAttributes类型为Anonymous Object

@{
  var hasDisabled=true; 
}

@Html.CheckBox("CheckBox1"
              , true
              , new { @class = "Class1"}
               .AddHtmlAttrItem("disabled", "disabled", hasDisabled))
.
Run Code Online (Sandbox Code Playgroud)

示例 2 HtmlAttributes键入为Dictionary<string, object>

@Html.CheckBox("CheckBox1"
              , true
              , new Dictionary<string, object> { { "class", "Class1" }
               .AddHtmlAttrItem("disabled", "disabled", hasDisabled))
.
Run Code Online (Sandbox Code Playgroud)

现在只需将hasDisabled值更改为trueorfalse即可!


示例3 (多个条件属性)

@{
  var hasDisabled=true;
  var hasMax=false ;
  var hasMin=true ;
}

@Html.CheckBox("CheckBox1"
              , true
              , new { @class = "Class1"}
               .AddHtmlAttrItem("disabled", "disabled", hasDisabled)
               .AddHtmlAttrItem("data-max", "100", hasMax)
               .AddHtmlAttrItem("data-min", "50", hasMin))
.
Run Code Online (Sandbox Code Playgroud)

  • 这太棒了,谢谢!不过有一点评论:我建议使用“HtmlHelper.AnonymousObjectToHtmlAttributes”而不是“UnderlineToDashInDictionaryKeys”,因为它已经是内置的。;) (3认同)