我有这个剃刀模板
<table> <tr> <td>@Html.RadioButtonFor(i => i.Value,"1")</td> <td>@Html.LabelFor(i => i.Value,"true")</td> </tr> <tr> <td>@Html.RadioButtonFor(i => i.Value,"0")</td> <td>@Html.LabelFor(i => i.Value,"false")</td> </tr> </table>
这给我这个HTML
<table> <tr> <td><input id="Items_1__Value" name="Items[1].Value" type="radio" value="1" /></td> <td><label for="Items_1__Value">true</label></td> </tr> <tr> <td><input checked="checked" id="Items_1__Value" name="Items[1].Value" type="radio" value="0" /></td> <td><label for="Items_1__Value">false</label></td> </tr> </table>
所以我有ID Items_1__Value两次,当然 – 不好,不工作在浏览器,当我点击第二个标签“假”的第一个广播将被激活。
我知道我可以在RadioButtonFor添加一个自己的ID,并用我的标签来引用,但这不是很好,是吗?特别是因为我在一个循环,不能只使用名称“值”与一个添加的数字,这将最终在多个Dom Ids在我的最终HTML标记以及。
应该不是一个很好的解决方案呢?
解决方法
我一直在想如何MVC确定“嵌套”字段名称和ID。它花了一些研究MVC源代码来找出,但我想我有一个很好的解决方案。
EditorTemplates和DisplayTemplates如何确定字段名称和ID
随着EditorTemplates和DisplayTemplates的引入,MVC框架添加了ViewData.TemplateInfo,其中包含当前的“字段前缀”,例如“Items [1]”。嵌套模板使用此来创建唯一的名称和ID。
创建我们自己的唯一ID:
TemplateInfo
类包含一个有趣的方法,GetFullHtmlFieldId
.我们可以使用它来创建我们自己的唯一ID,如:
@{string id = ViewData.TemplateInfo.GetFullHtmlFieldId("fieldName");} @* This will result in something like "Items_1__fieldName" *@
为了胜利
以下是如何为您的示例实现正确的行为:
<table> <tr> @{string id = ViewData.TemplateInfo.GetFullHtmlFieldId("radioTrue");} <td>@Html.RadioButtonFor(i => i.Value,"1",new{id})</td> <td>@Html.LabelFor(i => i.Value,"true",new{@for=id})</td> </tr> <tr> @{id = ViewData.TemplateInfo.GetFullHtmlFieldId("radioFalse");} <td>@Html.RadioButtonFor(i => i.Value,"0","false",new{@for=id})</td> </tr> </table>
其中将给你以下HTML:
<table> <tr> <td><input id="Items_1__radioTrue" name="Items[1].Value" type="radio" value="1" /></td> <td><label for="Items_1__radioTrue">true</label></td> </tr> <tr> <td><input checked="checked" id="Items_1__radioFalse" name="Items[1].Value" type="radio" value="0" /></td> <td><label for="Items_1__radioFalse">false</label></td> </tr> </table>
免责声明
我的剃刀语法是欠发达,所以请让我知道,如果这个代码有语法错误。
物有所值
这是非常不幸的,这个功能不是内置的RadioButtonFor。看来逻辑上所有渲染的单选按钮应该有一个ID是它的名称和值的组合,但事实并非如此 – 也许因为这将不同于所有其他Html助手。为此功能创建自己的扩展方法也是一个合理的选择。但是,它可能会棘手使用“表达式语法”…所以我建议重载.RadioButton(名称,值,…)而不是RadioButtonFor(表达式,…)。你可能想要一个.Label(名称,值)的重载。我希望一切都有意义,因为在那一段有很多“填空”。