【问题标题】:Adding data-* attributes to MVC3 through a view model attribute通过视图模型属性将 data-* 属性添加到 MVC3
【发布时间】:2012-03-02 00:28:42
【问题描述】:

我希望为我正在开发的网站创建一个不显眼的级联下拉系统。不过,我无法弄清楚如何让各种 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 属性的内置功能。

【问题讨论】:

    标签: asp.net-mvc-3 unobtrusive-javascript


    【解决方案1】:

    看到编辑 1+2,我认为您需要创建自己的扩展程序。既然你是dealing with dropdowns,你可以have a look at this implementationuse custom attributes via IMetadataAware

    IMetadataAware:这个接口可以通过一个属性类来实现,这样属性就可以在模型元数据创建过程中添加元数据,而无需编写自定义元数据提供者。此接口由 AssociatedMetadataProvider 类使用,因此此行为由从它派生的所有类继承,例如 DataAnnotationsModelMetadataProvider 类。


    这部分不再作为答案有用

    如果您想为生成的 HTML 添加自定义属性,您可以使用许多帮助程序上可用的 Object htmlAttributes 参数,例如在 @Html.ActionLink() 中。

    带有自定义 data-* 属性的示例,可用于在启用了 javascript 的客户端上以不显眼的方式启动用于编辑用户设置的模式对话框。 Bootstrap's modal 使用类似的东西。

    请注意,我是using underscores instead of dashes for the data attribute

    @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
    )
    

    【讨论】:

    • 谢谢,不过我尽量避免手动添加所有这些值。我希望 html 属性来自我正在创建的视图模型属性。
    • 哦,一定是漏掉了标题中的那部分。
    • 别担心,其他人发布了相同的答案,然后将其删除。我更新了我的问题,使其更清晰。
    • 我已经接受了这个作为答案,因为这几乎是我最终不得不做的事情。
    【解决方案2】:

    如果不使用编辑器/显示模板或 HtmlAttributes,您将无法做到这一点。

    模板的优势在于您可以轻松地在一处添加标签,并让它们在整个应用程序中传播。

    【讨论】:

      【解决方案3】:

      我使用UIHint 派生属性将属性从视图模型传递到编辑器模板,我昨天才了解了精彩的IMetadataAware 界面1

      请注意对基本构造函数的调用如何强制我编写的编辑器模板的名称,特别是为了将属性作为参数添加到实际的帮助器中。传递给UIHint 参数的KnownUiHints.SelectionOther 常量等于“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; }
      

      这会导致OtherEmploymentStatusSelectionOtherInput 编辑器模板呈现,而后者又会呈现我的SelectionOtherTextBoxFor 助手,并将属性作为参数传递。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-19
        相关资源
        最近更新 更多