2010-03-23 20 views
19

使用HTML助手時,根據條件設置屬性的最佳方法是什麼?例如如何在MVC中設置禁用htmlAttribute

<%if (Page.User.IsInRole("administrator")) {%> 
<%=Html.TextBoxFor(m => m.FirstName, new {@class='contactDetails'}%> 
<%} else {%> 
<%=Html.TextBoxFor(m => m.FirstName, new {@class='contactDetails', disabled = true}%> 
<%}%> 

必須有更好的方式來編程添加一個額外的KeyPair到匿名類型?不能使用

new { .... disabled = Page.User.IsInRole("administrator") ... } 

的瀏覽器採取任何禁用的屬性值,使得禁用

+0

你得到的錯誤是什麼? 'Page.User.IsInRole(...)'不起作用? – 2010-03-23 12:39:04

+0

沒有錯誤 - 只是想減少重複代碼的數量 – Ollie 2010-03-23 14:14:35

+0

http://stackoverflow.com/a/10207597/155899 – nfplee 2014-04-25 07:55:13

回答

14

我可以建議您使用mvccontrib.FluentHtml。

你可以做這樣的事情

<%=this.TextBox(m=>m.FirstNam).Disabled(Page.User.IsInRole("administrator"))%> 
+0

哇,真漂亮。本週末肯定會檢查出來! – 2010-08-13 07:35:59

2

你需要傳遞一個Dictionary<string, object>輸入,並添加if語句內disabled關鍵。

我建議對擴展方法進行重載,該方法需要bool disabled參數,並將其添加到的attributes參數創建的RouteValueDictionary。 (您也可以從RouteValueDictionary中刪除disabled條目,如果它是false,並且不帶另一個參數)

+0

如果你這樣做,它仍然會呈現一個「禁用」的屬性,大多數瀏覽器會將其視爲禁用不管殘疾人=「禁用」 – hunter 2010-03-23 12:44:27

+0

然後你需要使用字典。 – SLaks 2010-03-23 12:45:19

8

Page.User.IsInRole( 「管理員」)?空:新{禁用=「禁用」}

+2

+1好主意......(除非他需要其他屬性) – SLaks 2010-03-23 12:48:26

+1

我需要其他屬性 - 代碼重複是我試圖避免的 – Ollie 2010-03-23 13:13:29

0

您也可以定義這個PARAM這樣:

Page.User.IsInRole("administrator") 
    ? (object)new { @class='contactDetails'} 
    : (object)new { @class='contactDetails', disabled = true} 
+0

這是代碼重複我試圖避免 - 當你有很多屬性這就像雜亂 – Ollie 2010-03-23 13:14:27

+0

不知道我真的很喜歡它的可讀性,但是當使用匿名類型時,你必須爲每組屬性創建多個實例。 – 2010-03-23 13:25:17

4

使用@SLaks建議使用擴展方法,以及使用Jeremiah Clark's example Extension method我寫一個擴展方法所以我現在可以做

Html.TextBoxFor(m => m.FirstName,new{class='contactDetails', ...},Page.User.IsInRole("administrator")); 

不知道是否有更好的方法,雖然

public static class InputExtensions 
{ 

    public static IDictionary<string, object> TurnObjectIntoDictionary(object data) 
    { 
     var attr = BindingFlags.Public | BindingFlags.Instance; 
     var dict = new Dictionary<string, object>(); 
     if (data == null) 
      return dict; 
     foreach (var property in data.GetType().GetProperties(attr)) 
     { 
      if (property.CanRead) 
      { 
       dict.Add(property.Name, property.GetValue(data, null)); 
      } 
     } 
     return dict; 

    } 

    public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes, bool disabled) 
    { 
     IDictionary<string, object> values = TurnObjectIntoDictionary(htmlAttributes); 

     if (disabled) 
      values.Add("disabled","true"); 


     return htmlHelper.TextBoxFor(expression, values); 
    } 

    public static MvcHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes, bool disabled) 
    { 
     IDictionary<string, object> values = TurnObjectIntoDictionary(htmlAttributes); 

     if (disabled) 
      values.Add("disabled", "true"); 


     return htmlHelper.TextAreaFor(expression, values); 
    } 

    public static MvcHtmlString CheckBoxFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool>> expression, object htmlAttributes, bool disabled) 
    { 
     IDictionary<string, object> values = TurnObjectIntoDictionary(htmlAttributes); 

     if (disabled) 
      values.Add("disabled", "true"); 


     return htmlHelper.CheckBoxFor(expression, values); 
    } 
} 
+0

您應該用'RouteValueDictionary'替換'TurnObjectIntoDictionary'方法,這是所有擴展方法使用的方法。它應該更快。另外,你應該接受我的答案。 – SLaks 2010-03-23 21:13:51

+0

順便說一句,任何人都需要'使用System.Web.Mvc'和 '使用System.Web.Mvc.Html' – rohancragg 2010-09-22 11:22:03

+0

僅供參考,現在可以使用'HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)'函數,它返回一個' RouteValueDictionary'。我必須使用這個函數而不是'TurnObjectIntoDictionary(htmlAttributes)'的原因是'TurnObjectIntoDictionary'沒有在生成的HTML中將'data_bind =「foo」'屬性轉換爲'data-bind =「foo」'。 – 2015-12-17 22:28:30

1

你可能要考慮一個新的文本框方法編寫自己的HtmlHelper擴展類:

public static class HtmlHelperExtensions 
{ 
    public static MvcHtmlString TextBoxFor(this HtmlHelper htmlHelper, Expression<Func<TModel, TProperty>> expression, string cssClass, bool disabled) 
    { 
     return disabled 
      ? Html.TextBoxFor(expression, new {@class=cssClass, disabled="disabled"}) 
      : Html.TextBoxFor(expression, new {@class=cssClass}) 
    } 
} 

現在(如果這個新類是在同一個名字,或者你已經導入了新的命名空間到你的頁面標題,或在web.config的頁面部分),你可以做到這一點你的aspx頁面上:

<%=Html.TextBoxFor(m => m.FirstName, "contactDetails", Page.User.IsInRole("administrator")) %> 
1

創建於對象的擴展方法,將創建排除是空的任何屬性輸入對象的副本,並將其全部作爲字典返回,以便在MVC HtmlHelpers中輕鬆使用:

public static Dictionary<string, object> StripAnonymousNulls(this object attributes) 
{ 
    var ret = new Dictionary<string, object>(); 
    foreach (var prop in attributes.GetType().GetProperties()) 
    { 
     var val = prop.GetValue(attributes, null); 
     if (val != null) 
     ret.Add(prop.Name, val); 
    } 
    return ret; 
} 

不知道有關通過屬性反映的兩倍性能的影響,以及不喜歡的擴展方法的名稱很多,但似乎把工作做好......

new { 
     @class = "contactDetails", 
     disabled = Page.User.IsInRole("administrator") ? "true" : null 
    }.StripAnonymousNulls() 
12

它的工作原理對我來說也是......

<%: Html.DropDownList("SportID", (SelectList)ViewData["SportsSelectList"], "-- Select --", new { @disabled = "disabled", @readonly = "readonly" })%> 

<%= Html.CheckBoxFor(model => model.IsActive, new { @disabled = "disabled", @readonly = "readonly" })%> 
相關問題