#asp.net-mvc-3 #razor #html-helper #asp.net-mvc-templates
#asp.net-mvc-3 #razor #html-помощник #asp.net-mvc-templates
Вопрос:
Если я передаю атрибуты htmlAttributes в шаблон, например:
@Html.DisplayFor(m => m.FirstName, new { htmlAttributes = new { @class = "orangetxt strongtxt" } })
В моем шаблоне, как бы я вставил их в свой HTML:
<span @ViewData["htmlAttributes"]>@Model</span>
Это почти работает, но делает некоторые довольно странные вещи, поэтому я предполагаю, что это не тот путь.
Я понимаю, что могу выполнить это с помощью метода расширения HtmlHelper для отображения полного элемента HTML (в данном случае span) и передачи атрибутов таким образом, но есть ли способ просто отобразить атрибуты прямо в элементе HTML, как в приведенном выше примере?
Ответ №1:
Приведенный ниже метод расширения позволит мне преобразовать атрибуты 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>
Комментарии:
1. Хм, возможно, я здесь ошибаюсь, но мне кажется, что ваше предполагаемое использование, основанное на вопросе, не сработает .. возможно, вы можете указать, как вы используете помощника
Ответ №2:
Ответ Джерада Роуза хороший, но я столкнулся с парой проблем с ним:
- Он не преобразует символы подчеркивания в тире в именах атрибутов
- Он не обрабатывает атрибуты, не имеющие значения, корректно
Чтобы решить первую проблему, используйте HtmlHelper.AnonymousObjectToHtmlAttributes
.
Ниже приведена моя модификация метода Джерада:
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)))));
}
Ответ №3:
Попробуйте это вместо,
@Html.DisplayFor(m => m.FirstName,
new { htmlAttributes = "class = orangetxt strongtxt"})
Это приведет к отображению строки, в то время как ваша версия делала странные вещи, отображаемые {
}
как часть вывода.
Комментарии:
1. Это близко, но все же не совсем то, что я ищу. Я действительно не хочу иметь дело со всеми преобразованиями и кодировками строк. На самом деле я придумал метод расширения для отображения атрибутов HTML и опубликую его ниже.
2. @JeradRose — в зависимости от того, что у вас есть, ничего не меняется, кроме фактического вызова Displayfor, поэтому никаких преобразований и кодирования
3. Да, но выше был только пример. У меня могут быть случаи, когда атрибуты должны быть немного более сложными и требовать кавычек. Например, если мне нужно включить
class = "orangetxt strongtxt" id = "myId"
, то использование вашего решения начинает становиться немного сумасшедшим.4. @JeradRose — справедливо, я не уловил часть об использовании нескольких атрибутов, мой плохой…
Ответ №4:
DisplayFor()
используется для отображения шаблона, соответствующего типу свойства.
Шаблоны отображения — это файлы .cshtml внутри папки /DisplayTemplates, которая, в свою очередь, находится внутри папки просмотра (т. Е. Любой папки из домашней, общей или даже определенного контроллера).
Пример.
Если у вас есть шаблон String.cshtml, подобный этому, внутри /Views/Shared:
@model String
@if (string.IsNullOrEmpty(Model)) {
<span>(no string)</span>
}
else {
<span>@Model</span>
}
Каждый раз, когда вы вызываете DisplayFor()
свойство string:
DisplayFor(model => model.MyStringProperty);
Он отображает шаблон в соответствии со значением строки. Вы можете быть более конкретными и поместить / DisplayTemplates в определенную папку представления, и шаблон влияет только на вызовы из этих представлений.
В вашем случае вы можете быть еще более конкретными и вызывать DisplayFor()
с определенным шаблоном.
Предположим, у вас есть шаблон для определенного свойства, называемого MyPropertyTemplate.cshtml. Вы бы назвали DisplayFor()
так:
DisplayFor(model => model.MyProperty, "MyPropertyTemplate");
И у них внутри этого шаблона вы можете иметь любые атрибуты HTML, которые вы хотите.
@model MyProperty
<span class="orangetxt strongtxt">@MyProperty.ToString()</span>
PS: Когда он не находит шаблон, я думаю, он вызывает только model.Property.ToString()
без дополнительного html.
К вашему сведению: EditorFor()
, например, работает аналогичным образом, но использует папку /EditorTemplates .
Комментарии:
1. Спасибо. Я понимаю, как работают шаблоны, мне просто нужно выяснить, как передавать атрибуты htmlAttributes в шаблон и отображать их, как в примере выше, без их жесткого кодирования в новом шаблоне. Я хочу, чтобы они были более гибкими.
2. Проблема с шаблонами, Джерад, в том, куда идут атрибуты htmlAttributes? У вас может быть огромный шаблон со многими разделениями, а что нет. То, что вы хотите сделать, будет очень нестандартным, и в основном это включает в себя написание собственных методов HtmlHelper для вывода с помощью пользовательских атрибутов htmlAttributes.
3. Правда, я понимаю, что со сложными шаблонами трудно понять, к чему
htmlAttributes
они будут применены. В моем случае он всегда будет применяться к элементу, непосредственно окружающему значение модели. Если бы я хотел, скажем, включить другую опцию для применения пользовательских атрибутов к метке, то я мог бы добавить поддержкуlabelHtmlAttributes
, например.