Добавление атрибутов data- * в MVC3 через атрибут модели представления - PullRequest
3 голосов
/ 09 февраля 2012

Я ищу создание ненавязчивой каскадной системы для сайта, над которым я работаю.У меня возникают проблемы с выяснением того, как заставить различные методы HtmlHelper включать настраиваемые атрибуты html в отображаемый тег.

Просматривая источник встроенных методов HtmlHelper, они все вызываютGetUnobtrusiveValidationAttributes, который создает все атрибуты data-val- * html.Прекрасно, если вам нужны атрибуты валидатора, но я хотел бы иметь возможность добавлять другие атрибуты таким образом без необходимости изменять шаблоны и создавать новые расширения HtmlHelper.

Возможно ли это вообще?Я что-то пропускаю?

Редактировать

Я знаю, что все методы HtmlHelper имеют перегрузку, которая принимает объект с атрибутами html.Я пытаюсь избежать этого, если это вообще возможно.

Редактировать 2

Я, по сути, хочу, чтобы это произошло:

public class ViewModel
{
    [Cascading(Action="/Controller/Action")]
    public int Action { get; set; }
}

А затем HtmlHelpers визуализируется как:

<select data-action="/Controller/Action"></select>

Но желательно без необходимости писать метод расширения для этого.У меня нет проблем с созданием собственного вспомогательного метода для этого, но мне интересно, не хватает ли мне какой-то встроенной функции, которая уже просматривает метаданные случайной модели и может добавлять атрибуты html.

Ответы [ 3 ]

2 голосов
/ 09 февраля 2012

Видя правку 1 + 2, я думаю, вам нужно создать свои собственные расширения.Поскольку вы имеете дело с выпадающими списками , вы можете взглянуть на эту реализацию , но использовать пользовательские атрибуты через IMetadataAware.

IMetadataAware: этот интерфейс может быть реализован с помощью класса атрибута, чтобы атрибут мог добавлять метаданные в процесс создания метаданных модели без написания настраиваемого поставщика метаданных.Этот интерфейс используется классом AssociatedMetadataProvider, поэтому это поведение наследуется всеми производными от него классами, такими как класс DataAnnotationsModelMetadataProvider.


Эта часть больше не используется, посколькуответ

Если вы хотите добавить пользовательские атрибуты в сгенерированный HTML, вы можете использовать параметр Object htmlAttributes, доступный для многих помощников, например, в @Html.ActionLink().

Пример с пользовательскими атрибутами data-*, которые можно использовать для ненавязчивого запуска модального диалога для редактирования пользовательских настроек на клиентах с поддержкой javascript. Модал Bootstrap использует нечто похожее на это.

Обратите внимание, что я использую подчеркивания вместо черточек для атрибута данных .

@Html.ActionLink(
    "Settings",
    "CreateOrUpdate",
    "User",
    new { id = "1234" },
    new {
        title = "Edit your personal settings", 
        data_show_modal = "#my-user-settings-modal"
    })

В вашем случае, я полагаю, вы используете @Html.DropDownList(...), что также занимает htmlAttributes.Заполните их так, как вам нравится, и пусть ваш javascript подберет нужные data-* атрибуты.

public static MvcHtmlString DropDownList(
    this HtmlHelper htmlHelper,
    string name,
    IEnumerable<SelectListItem> selectList,
    string optionLabel,
    Object htmlAttributes
)
0 голосов
/ 08 марта 2013

Я использую производный атрибут UIHint для доставки свойств из модели представления в шаблон редактора с замечательным IMetadataAware интерфейсом 1 , о котором я узнал только вчера.

Обратите внимание, как вызов базового конструктора вызывает имя шаблона редактора, который я написал специально для добавления атрибутов к фактическому помощнику в качестве параметров.Константа KnownUiHints.SelectionOther, передаваемая параметру UIHint, равна «SelectionOtherInput», названию шаблона редактора.

Параметры помощника доступны для кода помощника.

НапримерМой DropDownAttribute передает свойства со следующим кодом:

public class SelectionOtherInputAttribute : UIHintAttribute, IMetadataAware
{
    public SelectionOtherInputAttribute(string selectionElementName) : base(KnownUiHints.SelectionOther, KnownPresentationLayers.Mvc)
    {
        SelectionElementName = selectionElementName;
    }
    public SelectionOtherInputAttribute(string selectionElementName, object otherSelectionKey) : base(KnownUiHints.SelectionOther, KnownPresentationLayers.Mvc)
    {
        SelectionElementName = selectionElementName;
        ControlParameters[SelectionOtherInputControlParameterKeys.OtherSelectionKey] = otherSelectionKey;
    }
    public string SelectionElementName { get; set; }
    public object OtherSelectionKey { get; set; }
    public void OnMetadataCreated(ModelMetadata metadata)
    {
        metadata.AdditionalValues["@OtherSelectionAttrinbuteNames.SelectionElementName"] = SelectionElementName;
        metadata.AdditionalValues["@OtherSelectionAttrinbuteNames.OtherSelectionKey"] = OtherSelectionKey;
    }
}

Вот мой шаблонный редактор SelectionOtherInput.

@using OtherInput.Core
@{
    var meta = ViewData.ModelMetadata.AdditionalValues;
    var selectionElementName = (string)meta["@OtherSelectionAttrinbuteNames.SelectionElementName"];
    var otherSelectionKey = meta["@OtherSelectionAttrinbuteNames.OtherSelectionKey"];
    var inputElementname = ViewData.TemplateInfo.HtmlFieldPrefix;
}
@Html.SelectionOtherTextBoxFor(m => Model, selectionElementName, otherSelectionKey.ToString())

Затем я использую свой атрибут в модели представления следующим образом:

[SelectionOtherInput("EmploymentStatusId", 1)]
public string OtherEmploymentStatus { get; set; }

Это приводит к визуализации OtherEmploymentStatus шаблоном редактора SelectionOtherInput, который, в свою очередь, отображаетmy SelectionOtherTextBoxFor helper, с атрибутами, переданными в качестве аргументов.

0 голосов
/ 09 февраля 2012

Вы не можете сделать это без использования редактора / шаблонов отображения или HtmlAttributes.

Шаблоны имеют то преимущество, что вы можете легко добавлять теги в одном месте и распространять их по всему приложению.

...