提问人:rossisdead 提问时间:2/9/2012 最后编辑:rossisdead 更新时间:3/8/2013 访问量:3512
通过视图模型属性向 MVC3 添加 data-* 属性
Adding data-* attributes to MVC3 through a view model attribute
问:
我希望为我正在开发的网站创建一个不显眼的级联下拉系统。不过,我无法弄清楚如何让各种 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 属性的内置功能。
答:
看到编辑 1+2,我认为您需要创建自己的扩展。由于您正在处理下拉列表,因此可以查看此实现,但通过 IMetadataAware
使用自定义属性。
IMetadataAware
:此接口可由属性类实现,以便属性可以将元数据添加到模型元数据创建过程中,而无需编写自定义元数据提供程序。此接口由 AssociatedMetadataProvider 类使用,因此此行为由派生自它的所有类(如 DataAnnotationsModelMetadataProvider 类)继承。
这部分不再作为答案
如果要将自定义属性添加到生成的 HTML 中,可以使用许多帮助程序上可用的参数,例如在 @Html.ActionLink()
中。Object htmlAttributes
具有自定义属性的示例,这些属性可用于不显眼地启动模式对话框,用于在启用 javascript 的客户端上编辑用户设置。Bootstrap 的模态使用与此类似的东西。data-*
请注意,我使用下划线而不是破折号作为数据属性。
@Html.ActionLink(
"Settings",
"CreateOrUpdate",
"User",
new { id = "1234" },
new {
title = "Edit your personal settings",
data_show_modal = "#my-user-settings-modal"
})
在您的情况下,我猜您正在使用 @Html.DropDownList(...),
这也需要。随心所欲地填充它们,让你的 javascript 选择正确的属性。htmlAttributes
data-*
public static MvcHtmlString DropDownList(
this HtmlHelper htmlHelper,
string name,
IEnumerable<SelectListItem> selectList,
string optionLabel,
Object htmlAttributes
)
评论
如果不使用编辑器/显示模板或 HtmlAttributes,就无法做到这一点。
这些模板的优点是,您可以在一个位置轻松添加标记,并让它们传播到整个应用程序。
我使用派生属性将属性从视图模型传递到编辑器模板,以及我昨天才知道的精彩界面1。UIHint
IMetadataAware
请注意,对基构造函数的调用如何强制使用我编写的编辑器模板的名称,特别是将属性作为参数添加到实际帮助程序中。传递给参数的常量等于编辑器模板的名称“SelectionOtherInput”。KnownUiHints.SelectionOther
UIHint
然后,帮助程序参数可供帮助程序代码使用。
例如,My 使用以下代码传达属性: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
SelectionOtherTextBoxFor
评论