2011-06-14 57 views
30

我已經創建了一個默認的MVC 3項目(使用剃鬚刀),爲了演示一個問題。TextBoxFor vs EditorFor和htmlAttributes vs additionalViewData

在登錄頁面上,有一行:

@Html.TextBoxFor(m => m.UserName) 

如果我更改爲:

@Html.TextBoxFor(m => m.UserName, new { title = "ABC" }) 

然後將它呈現爲(具有title屬性):

<input data-val="true" data-val-required="The User name field is required." id="UserName" name="UserName" title="ABC" type="text" value="" /> 

但是,如果我讓它成爲EditorFor:

@Html.EditorFor(m => m.UserName, new { title = "ABC" }) 

然後它被渲染(沒有title屬性)爲:

<input class="text-box single-line" data-val="true" data-val-required="The User name field is required." id="UserName" name="UserName" type="text" value="" /> 

因此,在總結,當我使用EditorFor title屬性丟失。

我知道TextBoxFor的第二個參數叫做htmlAttributes,對於EditorFor而言,它是additionalViewData,但是我見過的例子EditorFor可以呈現這個參數提供的屬性。

任何人都可以請解釋我做錯了什麼,以及如何使用EditorFor時我可以有一個標題屬性?

+0

奇妙的是,我要問的確切問題。 – aknuds1 2011-12-13 14:30:05

回答

5

你可以看看這說明如何實現自定義元數據提供商,並在您的視圖模型中使用的數據標註,以便定義HTML屬性,如classmaxlengthtitle,...這可能則是following blog post與模板助手一起使用。

+3

令人印象深刻的是,該解決方案是用於核桃的衆所周知的大錘。有沒有更微妙的解決方案? – 2011-06-14 18:38:36

+1

@G-單位,沒有沒有。 EditorFor不支持傳遞html屬性。這是沒有道理的,因爲你甚至不知道模板如何實現。它可能是一個自定義模板,其HTML屬性沒有意義。因此,實現這一目標的唯一方法是編寫自定義元數據提供程序。就個人而言,這是我使用的,我對結果很滿意。 – 2011-06-14 18:40:18

+0

謝謝,我鞠躬致敬! – 2011-06-16 09:40:02

12

在MVC3中,如果您創建自定義EditorFor模板,則可以使用這種解決方法添加標題(和其他htmlAttributes)。這種情況對於價值準備是可選的,editorFor不需要調用包括object additionalViewData

@Html.EditorFor(m => m.UserName, "CustomTemplate", new { title = "ABC" }) 

EditorTemplates/CustomTemplate.cshtml

@{ 
    string s = ""; 
    if (ViewData["title"] != null) { 
     // The ViewData["name"] is the name of the property in the addtionalViewData... 
     s = ViewData["title"].ToString(); 
    } 
} 

@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { title = s }) 

我確實非常相似,包括可選的類的東西一個EditorTemplate。您可以隨意添加儘可能多的項目到addtionalViewData,但您需要在EditorFor模板中處理每個項目。

14

我想我找到了一個更好的解決方案。 EditorFor將additionalViewData作爲參數。如果你給它一個參數名爲「htmlAttributes」與屬性,那麼我們可以做有趣的事情吧:

@Html.EditorFor(model => model.EmailAddress, 
       new { htmlAttributes = new { @class = "span4", 
              maxlength = 128, 
              required = true, 
              placeholder = "Email Address", 
              title = "A valid email address is required (i.e. [email protected])" } }) 

在模板(在這種情況下,EmailAddress的。CSHTML),然後你可以提供一些默認的屬性:

@Html.TextBox("", 
       ViewData.TemplateInfo.FormattedModelValue, 
       Html.MergeHtmlAttributes(new { type = "email" })) 

魔術通過這個輔助方法走到一起:

public static IDictionary<string, object> MergeHtmlAttributes<TModel>(this HtmlHelper<TModel> htmlHelper, object htmlAttributes) 
{ 
    var attributes = htmlHelper.ViewData.ContainsKey("htmlAttributes") 
          ? HtmlHelper.AnonymousObjectToHtmlAttributes(htmlHelper.ViewData["htmlAttributes"]) 
          : new RouteValueDictionary(); 

    if (htmlAttributes != null) 
    { 
     foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(htmlAttributes)) 
     { 
      var key = property.Name.Replace('_', '-'); 
      if (!attributes.ContainsKey(key)) 
      { 
       attributes.Add(key, property.GetValue(htmlAttributes)); 
      } 
     } 
    } 

    return attributes; 
} 

當然,你可以修改它渲染的屬性,以及如果你正在做的原始HTML:

public static MvcHtmlString RenderHtmlAttributes<TModel>(this HtmlHelper<TModel> htmlHelper, object htmlAttributes) 
{ 
    var attributes = htmlHelper.ViewData.ContainsKey("htmlAttributes") 
          ? HtmlHelper.AnonymousObjectToHtmlAttributes(htmlHelper.ViewData["htmlAttributes"]) 
          : new RouteValueDictionary(); 

    if (htmlAttributes != null) 
    { 
     foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(htmlAttributes)) 
     { 
      var key = property.Name.Replace('_', '-'); 
      if (!attributes.ContainsKey(key)) 
      { 
       attributes.Add(key, property.GetValue(htmlAttributes)); 
      } 
     } 
    } 

    return MvcHtmlString.Create(String.Join(" ", 
     attributes.Keys.Select(key => 
      String.Format("{0}=\"{1}\"", key, htmlHelper.Encode(attributes[key]))))); 
} 
+0

你會提供一個完整的使用代碼的示例項目嗎?你發佈了嗎?我是ASP.NET新手,無法放置該'MergeHtmlAttributes'和'RenderHtmlAttributes'類。 – 2013-02-25 03:33:53

+1

@RosdiKasim - 這些擴展方法通常存儲在一個靜態類中,該靜態類既可以映射常用HTML幫助器的命名空間,也可以存儲在Views文件夾的web.config中包含的新命名空間,因此我不必繼續在每個頁面上引用它。所以基本上是「HtmlHelperExtensions.cs」在項目或基礎設施文件夾的根目錄中。 – 2013-02-26 04:35:03

+0

好的,謝謝。我會試一試。 – 2013-02-27 08:45:44

相關問題