【问题标题】:MVC Radio Button Lists are not grouped when using the HtmlHelper class使用 HtmlHelper 类时,MVC 单选按钮列表不分组
【发布时间】:2011-07-21 15:20:45
【问题描述】:

在创建组合在一起的单选按钮列表时遇到问题,特别是在 MVC 3 中,但这也适用于 MVC 2。

当使用 Html 帮助程序生成单选按钮并且模型是数组的一部分时,就会出现问题。

这是我的代码的精简版。

public class CollectionOfStuff {
  public MVCModel[] Things { get; set }
}

/*This model is larger and represents a Person*/    
public class MVCModel {

  [UIHint("Hidden")]
  public string Id { get; set; }

  public string Name { get; set; }

  public bool IsSelected { get; set; }
}

/*Assigned to new CollectionOfStuff property Things*/    
var items = new[] { 
 new MVCModel() { Id="0" Name = "Name here" }, new MVCModel() { Id="1" Name = "Name there" } 
}

我的父母视图

@model CollectionOfStuff

@for (int i = 0; i < Model.Things.Length; i++) {
    @Html.EditorFor(m => m.Things[i]);
}

我的视图呈现单个 MVCModel 对象

@Model MVCModel

    @{
      var attr = new {
        Checked = Model.IsSelected ? "checked=checked" : ""
      };
    }

    @Html.RadioButtonFor(model => model, Model.Id, attr)

产生这个输出:

<input type="radio" value="0" name="MVCModel[0]" id="MVCModel_0_" data-val-required="You need to choose" data-val="true" />
<input type="radio" value="1" name="MVCModel[1]" id="MVCModel_1_" data-val-required="You need to choose" data-val="true" />

单选按钮没有分组,但它具有写出元数据以进行验证的明显优势。

另一种方法是调用:

@Html.RadioButton(name: "GroupName", value: Model.Id, isChecked: Model.IsSelected)     

生产:

<input type="radio" value="0" name="MVCModel[0].GroupName" id="MVCModel_0__GroupName">
<input type="radio" value="1" name="MVCModel[1].GroupName" id="MVCModel_1__GroupName">

同样,这不会产生预期的结果。它还缺少验证元数据。

另一种选择是创建自定义模板,但这种方法的问题是验证所需的所有元数据都不存在。

关于如何创建分组单选按钮或获取元数据以便我自己创建模板的任何想法?

【问题讨论】:

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


    【解决方案1】:

    您尚未展示您的视图模型的外观,但您可以按某些属性对它们进行分组。所以我们举个例子:

    public class MyViewModel
    {
        [Required]
        public string SomeProperty { get; set; }
    }
    

    控制器:

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View(new MyViewModel());
        }
    
        [HttpPost]
        public ActionResult Index(MyViewModel model)
        {
            return View(model);
        }
    }
    

    查看:

    @model AppName.Models.MyViewModel
    @using (Html.BeginForm())
    {
        <div>A: @Html.RadioButtonFor(x => x.SomeProperty, "a")</div>
        <div>B: @Html.RadioButtonFor(x => x.SomeProperty, "b")</div>
        @Html.ValidationMessageFor(x => x.SomeProperty)
        <input type="submit" value="OK" />
    }
    

    现在如果你想预选一些单选,只需将视图模型的属性设置为单选的相应值,而不是在你的视图中编写一些丑陋的 C# 代码:

    public ActionResult Index()
    {
        var model = new MyViewModel
        {
            SomeProperty = "a" // select the first radio
        };
        return View(model);
    }
    

    显然,这种技术适用于任何简单的属性类型(不仅是字符串)以及可以与该属性关联的任意数量的单选按钮。

    【讨论】:

    • 如果我像您建议的那样对两个单选按钮一个接一个地硬编码,那么您的解决方案就可以工作,但是当您的渲染模板位于项目循环中时,这将不起作用。看我的例子,你会看到数组的数字创建了与当前索引对应的新 id。
    • @Vince Panuccio,那么您的单选按钮不应该是集合的一部分。只需将这些属性移动到视图模型的根目录即可。
    • 所以如果我有一个模型数组并且我想知道用户选择了哪个模型,我不能这样做吗?我还在我的问题中添加了模型。
    • @Vince Panuccio,当然可以:在这种情况下,您定义一个视图模型,在其中放置与单选按钮相对应的属性和与您正在谈论的集合相对应的另一个属性,然后制作你的视图强类型化到这个新的视图模型。这就是视图模型:它们应该反映您的视图模型逻辑。或者,如果这些单选按钮确实需要成为集合的一部分,那么这意味着该集合的每个项目都将获得自己的单选组。由您决定您需要什么。两者都有可能。
    • @Darin Dimitrov 我完全有你所拥有的,但就我而言,我有多个问题,每个问题都有 3 个单选按钮。我需要在每个问题级别对我的单选按钮进行分组。在遵循您所拥有的之后,我的单选按钮被全面分组。我该如何解决这个问题?
    猜你喜欢
    • 2012-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-02
    • 2015-06-06
    • 1970-01-01
    • 2019-10-15
    相关资源
    最近更新 更多