2011-10-19 45 views
9

如果我傳遞HtmlAttributes成模板,像這樣:添加HtmlAttributes到模板

@Html.DisplayFor(m => m.FirstName, new { htmlAttributes = new { @class = "orangetxt strongtxt" } }) 

在我的模板,我怎麼會注入到這些我的HTML:

<span @ViewData["htmlAttributes"]>@Model</span> 

這幾乎工程,但它有一些非常奇怪的東西,所以我認爲這不是要走的路。

我知道我可以使用HtmlHelper擴展方法來完成此操作,以呈現完整的HTML元素(在本例中爲span),並以這種方式傳遞屬性,但有沒有辦法將屬性直接呈現爲HTML元素,就像上面的例子一樣?

回答

8

下面的擴展方法可以讓我HtmlAttributes轉換爲字符串:

public static MvcHtmlString RenderHtmlAttributes<TModel>(
     this HtmlHelper<TModel> htmlHelper, object htmlAttributes) 
    { 
     var attrbituesDictionary = new RouteValueDictionary(htmlAttributes); 

     return MvcHtmlString.Create(String.Join(" ", 
      attrbituesDictionary.Select(
       item => String.Format("{0}=\"{1}\"", item.Key, 
       htmlHelper.Encode(item.Value))))); 
    } 

然後,在標籤內使它們,我可以做到這一點:

<span @Html.RenderHtmlAttributes(ViewData["htmlAttributes"])>@Model</span> 
+0

嗯,我可能在這裏是錯的,但你的預期用法基於這個問題,在我看來是行不通的。你能否包括你如何使用幫手? – Ahmad

0

DisplayFor()用於呈現與屬性類型匹配的模板。

顯示模板是.cshtml文件內部/DisplayTemplates夾這又是一個視圖文件夾內(即任何從家,共享文件夾或甚至特定的控制器)。

一個例子。

如果您在一個String.cshtml模板像這裏面/瀏覽/分享

@model String 

@if (string.IsNullOrEmpty(Model)) { 
    <span>(no string)</span> 
} 
else { 
    <span>@Model</span> 
} 

每次調用DisplayFor()一個字符串屬性時間:

DisplayFor(model => model.MyStringProperty); 

它相應地將模板呈現爲字符串的值。您可以更具體地將/DisplayTemplates放置在特定的View文件夾中,並且只有來自這些視圖的調用受到模板的影響。


你的情況,你可以更加具體,並呼籲DisplayFor()與特定的模板。

假設您有一個特定屬性的模板,名爲MyPropertyTemplate.cshtml。你會打電話DisplayFor()這樣的:

DisplayFor(model => model.MyProperty, "MyPropertyTemplate"); 

而他們,在模板中,你可以有你想要的任何HTML屬性。

@model MyProperty 

<span class="orangetxt strongtxt">@MyProperty.ToString()</span> 

PS:如果它沒有找到一個模板,我想這只是沒有額外的HTML調用model.Property.ToString()

例如:EditorFor(),例如,以類似的方式工作,但它使用/EditorTemplates文件夾。

+1

感謝。我理解模板是如何工作的,我只需要弄清楚如何將HtmlAttributes傳遞給模板並像上面的例子那樣渲染它們,而不用在新模板中對它們進行硬編碼。我希望他們更靈活。 –

+1

模板Jerad的問題是htmlAttributes去哪裏?你可以有一個巨大的模板與許多divs,而不是。你想要做的將是非常自定義的,它基本上涉及編寫你自己的HtmlHelper方法來輸出自定義htmlAttributes。 – Buildstarted

+1

的確,我知道使用複雜的模板時,很難知道'htmlAttributes'會應用於什麼。就我而言,它將始終應用於緊鄰模型值的元素。例如,如果我想要包含另一個將自定義屬性應用於標籤的選項,那麼我可以添加對'labelHtmlAttributes'的支持。 –

1

試試這個,

@Html.DisplayFor(m => m.FirstName, 
       new { htmlAttributes = "class = orangetxt strongtxt"}) 

這會使一個字符串,而你的版本沒有做怪異的東西,呈現{}作爲輸出的一部分。

+0

這很接近,但仍然不完全是我在找的東西。我真的不想處理所有的字符串轉換和編碼。我實際上想出了一個擴展方法來呈現HTML屬性,並將在下面發佈。 –

+0

@JeradRose - 根據你目前的狀況,沒有任何變化,除了實際調用Displayfor所以沒有轉換和編碼 – Ahmad

+1

是的,但以上只是一個例子。我可能會遇到這樣的情況:屬性需要更復雜一些,並且需要引號。例如,如果我需要包含'class =「orangetxt strongtxt」id =「myId」',那麼它開始使用你的解決方案有點瘋狂。 –

3

Jerad羅斯的答案是好的,但我遇到了幾個問題:

  • 它不會將下劃線轉換爲屬性中的破折號名
  • 它不處理無值屬性擺好

爲了解決第一個問題,使用HtmlHelper.AnonymousObjectToHtmlAttributes

下面是我Jerad的方法的調整:

public static MvcHtmlString RenderHtmlAttributes(this HtmlHelper helper, object htmlAttributes) 
{ 
     if (htmlAttributes == null) return new MvcHtmlString(String.Empty); 
     var attrbituesDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); 
     return new MvcHtmlString(String.Join(" ", attrbituesDictionary.Select(item => string.IsNullOrEmpty((string)item.Value) ? String.Format("{0}", item.Key) : String.Format("{0}=\"{1}\"", item.Key, helper.Encode(item.Value))))); 
}