2011-10-19 15 views
9

Jeśli jestem przechodzącej HtmlAttributes do szablonu, tak:Dodawanie HtmlAttributes do szablonu

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

W moim szablonu, jak bym wstrzyknąć je w moim HTML:

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

To prawie działa, ale robi trochę dziwnych rzeczy, więc zakładam, że to nie jest droga.

Rozumiem, że mogę to zrobić za pomocą metody rozszerzenia HtmlHelper, aby renderować pełny element HTML (w tym przypadku zakres) i przekazywać atrybuty w ten sposób, ale czy istnieje sposób na renderowanie atrybutów bezpośrednio w elemencie HTML , jak powyższy przykład?

Odpowiedz

8

Poniższa metoda rozszerzenie pozwoli mi przekształcić HtmlAttributes do łańcucha:

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))))); 
    } 

Następnie, aby uczynić je w tagu, mogę po prostu to zrobić: odpowiedź

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

Hmm i może się mylę tutaj, ale twoje zamierzone użycie jako oparte na pytaniu, wydaje mi się nie działa. czy możesz uwzględnić sposób, w jaki używasz pomocnika? – Ahmad

0

DisplayFor() służy do renderowania szablonu zgodnego z typem właściwości.

Szablony wyświetlania to pliki .cshtml wewnątrz folderu /DisplayTemplates, który z kolei znajduje się w folderze widoku (tj. Dowolnym folderze z Home, Shared lub nawet określonego kontrolera).

Przykład.

Jeśli ve String.cshtml szablon tak wewnątrz /Views/Shared:

@model String 

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

każdym razem dzwonić DisplayFor() na właściwości String:

DisplayFor(model => model.MyStringProperty); 

To renderuje szablon odpowiednio do wartości ciągu. Możesz być bardziej konkretny i umieścić /DisplayTemplates wewnątrz określonego folderu Widok, a szablon wywoła tylko te wywołania z tych widoków.


W twoim przypadku może być nawet bardziej szczegółowe i nazywają DisplayFor() z konkretnego szablonu.

Załóżmy, że masz szablon dla określonej właściwości o nazwie MyPropertyTemplate.cshtml. nazwałbyś DisplayFor() tak:

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

a nimi, wewnątrz tego szablonu można mieć cokolwiek chcesz atrybutów HTML.

@model MyProperty 

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

PS: Jeśli nie znajdzie szablon Chyba tylko nazywa model.Property.ToString() bez dodatkowego html.

FYI: EditorFor(), na przykład, działa w podobny sposób, ale używa folderu /EditorTemplates.

+1

Dzięki. Rozumiem, jak działają szablony, po prostu muszę wymyślić, jak przekazać HtmlAttributes do szablonu i renderować je tak, jak w powyższym przykładzie, bez twardego kodowania w nowym szablonie. Chcę, żeby były bardziej elastyczne. –

+1

Problem z szablonami, Jerad, gdzie się dzieje w htmlAttributes? Możesz mieć ogromny szablon z wieloma elementami div, a co nie. To, co chcesz zrobić, będzie bardzo niestandardowe i polega w zasadzie na pisaniu własnych metod HtmlHelper do wyprowadzania z niestandardowymi atrybutami htmlAttributes. – Buildstarted

+1

To prawda, rozumiem, że w przypadku złożonych szablonów trudno jest się zorientować, do czego zostanie zastosowane "atrybut html". W moim przypadku zawsze zostanie zastosowany do elementu bezpośrednio otaczającego wartość modelu. Jeśli chciałem, na przykład, dołączyć inną opcję zastosowania niestandardowych atrybutów do etykiety, to mógłbym na przykład dodać obsługę 'labelHtmlAttributes'. –

1

Spróbuj zamiast tego

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

To uczyni ciąg, natomiast wersja robił dziwne rzeczy, wydanego {} jako część produkcji.

+0

To jest blisko, ale wciąż nie jest dokładnie tym, czego szukam. Naprawdę nie chcę mieć do czynienia z całą konwersją ciągów i kodowaniem. Tak naprawdę wymyśliłem metodę rozszerzenia do renderowania atrybutów HTML i opublikuję ją poniżej. –

+0

@JeradRose - w oparciu o bieżące dane nic się nie zmienia oprócz faktycznego połączenia z Displayfor, więc nie ma konwersji i kodowania – Ahmad

+1

Tak, ale powyższy był tylko przykładem. Mogę mieć przypadki, w których atrybuty muszą być nieco bardziej złożone i będą wymagać wyceny. Na przykład, jeśli muszę dołączyć 'class =" orangetxt strongtxt "id =" myId "', to zaczyna się trochę zwariować używając twojego rozwiązania. –

3

Jerad Rose jest dobry, ale wystąpiły z nim kilka problemów:

  • Nie zamienia podkreśleń na kreski w atrybucie Nazwy
  • To nie obsługuje bez wartości atrybutów wdzięcznie

Aby rozwiązać pierwszy problem, użyj HtmlHelper.AnonymousObjectToHtmlAttributes.

Poniżej moja modyfikacja metody Jerad za:

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))))); 
}