【问题标题】:Radio Button generates duplicate HTML id-s单选按钮生成重复的 HTML id-s
【发布时间】:2011-02-17 14:05:53
【问题描述】:

似乎默认的 ASP.NET MVC2 Html 帮助程序在使用这样的代码 (EditorTemplates/UserType.ascx) 时会生成重复的 HTML ID

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<UserType>" %>

<%: Html.RadioButton("", UserType.Primary, Model == UserType.Primary) %>
<%: Html.RadioButton("", UserType.Standard, Model == UserType.Standard) %>
<%: Html.RadioButton("", UserType.ReadOnly, Model == UserType.ReadOnly) %>

它生成的 HTML 是:

<input checked="checked" id="UserType" name="UserType" type="radio" value="Primary" /> 
<input id="UserType" name="UserType" type="radio" value="Standard" /> 
<input id="UserType" name="UserType" type="radio" value="ReadOnly" /> 

这清楚地表明了一个问题。所以我一定是在滥用 Helper 什么的。

我可以手动将id 指定为 html 属性,但我不能保证它是唯一的。

所以问题是如何确保 RadioButton 帮助器生成的 ID 对于每个值都是唯一的,并且仍然保留生成这些 ID 的约定(因此嵌套模型是否受到尊重?(最好不要手动生成 ID。)

【问题讨论】:

    标签: html asp.net-mvc asp.net-mvc-2 radio-button html-helper


    【解决方案1】:

    除了 PanJanek 的回答:
    如果你真的不需要元素有id,你也可以在helpers的htmlAttributes(即new { id="" })参数中指定id=""。这将导致 id 属性在生成的 html 中被完全忽略。

    来源:https://stackoverflow.com/a/2398670/210336

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题。手动指定 ID 似乎是唯一的解决方案。如果您不需要任何东西(如 javascript)的 id,但只希望它是唯一的,您可以为它们生成 Guid:

      <%: Html.RadioButton("", UserType.Primary, Model == UserType.Primary, new { id="radio" + Guid.NewGuid().ToString()}) %>
      

      更优雅的解决方案是在HtmlHelper 上创建您自己的扩展方法,以将 ID 创建逻辑与视图分开。比如:

      public static class HtmlHelperExtensions
      {
      
          public static MvcHtmlString MyRadioButtonFor<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression, bool value)
          {
              string myId = // generate id...
              return htmlHelper.RadioButtonFor(expression, value, new {id=myId});
          }
      }
      

      helper 方法可以使用 ViewContext 和 Model 数据来创建更有意义的 ID。

      更新:

      如果你使用 EditorTemplates 来呈现这样的控件

      <%= Html.EditorFor(m=>m.User, "MyUserControl") %>
      

      然后在 MyUserControl.ascx(放置在 ~/Views/Shared/EditorTemplates)中,您可以使用 ViewData.TemplateInfo.HtmlFieldPrefix 属性访问父控件 ID 或使用 Html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId("MyPostfixPart") 生成前缀 ID。这些方法可以在上面的辅助扩展中使用。 这同样适用于使用Html.Editor(...)Html.EditorForModel(...) 呈现的控件。在 Html.Editor 帮助器中,您还可以根据需要手动指定 htmlFiledName。

      当你嵌入控件时

      <%= Html.Partial("UserControl", Model.User) %>
      

      生成有意义的 ID 更加困难,因为 Html.Partial 不会提供有关前缀的信息 - ViewData.TemplateInfo.HtmlFieldPrefix 将始终为空。然后,唯一的解决方案是手动将前缀作为模型字段的 ViewData 键传递给 ascx 控件,这不像前一个解决方案那样优雅。

      【讨论】:

      • 也许您还可以建议如何在考虑模型当前名称的情况下生成 ID,以便可以正确生成 ID 并具有如下 ID:UserType_PrimaryCompany_User_UserType_Primary 等?跨度>
      • @Dmitriy:我刚刚更新了我的回复。 ViewData.TemplateInfo.HtmlFieldPrefix 应该可以帮到你。
      • 非常感谢。这应该对我有用。
      【解决方案3】:

      如果您确实需要通过 jQuery 访问单选按钮,我发现设置 id 的更好位置通常是在页面上,接近其预期用途。我也是这样做的:

      @Html.Label(Resource.Question)
      @Html.RadioButtonFor(m => m.Question, true, new {id = "QuestionYes"}) Yes
      @Html.RadioButtonFor(m => m.Question, false, new {id = "QuestionNo"}) No
      

      然后是我的 jQuery:

      if ($("input[id='QuestionNo']").is(":checked")) {
              $('#YesOptionalBlock').removeClass('showDiv');
              $('#YesOptionalBlock').addClass('hideDiv');
      }
      

      【讨论】:

        猜你喜欢
        • 2013-11-27
        • 1970-01-01
        • 2016-04-25
        • 2016-01-23
        • 2014-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多