ASP.NET MVC RadioButton Update布尔值

时间:2014-01-02 20:28:45

标签: c# asp.net-mvc razor radio-button

我有一张表格:

Form

用户可以添加/更新/删除某人的姓名。名称是List<NameViewModel> PersonViewModel Primary我对Html.RadioButtonFor单选按钮有疑问。我需要所有名称都在radiobutton组中,只允许一个Primary。

目前,如果我使用IsPrimary,则所有按钮都被赋予不同的名称,因此不在同一组中,并且它们的<input type="radio" name="radioName"/> 布尔属性不会在回发上设置。我可以用:

{{1}}

保持分组正确,但我不确定如何确保在回发时正确设置IsPrimary布尔属性。有人可以给我指导吗?非常感谢你。

2 个答案:

答案 0 :(得分:1)

现在这是一个直截了当的问题。由于所有单个NameViewModel项都需要保留其唯一名称,因此MVC模型绑定器可以正确识别和绑定模型。 (我相信你已经猜到了。)

所以现在我们没有单选按钮控件的名称来管理“组”。该名称也用于HTTP Post中以标识控件的值。所以现在我们处于catch-22模型绑定器需要唯一的名称来绑定模型在post上,并且浏览器需要所有相同的名称才能按照你的说法运行。

现在您可以使用一些jQuery voodoo来执行此操作,例如绑定另一个data-,然后使用此名称绑定到每个控件的click事件。现在我认为这更像是一个黑客而不是一个解决方案,但可以做类似的事情。 (是的,这是基本的)

假设这个模型

public class PersonViewModel
{
    public PersonViewModel()
    {
        this.Names = new List<NameViewModel>();
    }

    public IList<NameViewModel> Names { get; set; }

}

public class NameViewModel
{
    public NameViewModel()
    {
        this.IsPrimary = false;
    }

    public int ID { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string MiddleName { get; set; }

    public bool IsPrimary { get; set; }

    public string FullName
    {
        get
        {
            return string.Format("{0}{1} {2}",
                                this.FirstName,
                                !string.IsNullOrWhiteSpace(this.MiddleName) ? " " + this.MiddleName : "",
                                this.LastName);
        }
    }

标记

@Html.RadioButtonFor(x => x.Names[i].IsPrimary, true, new { data_group = "myGroup" })

的Javascript

$(function () {
        $('input[type="radio"][data-group="myGroup"]').click(function () {
            $('input[type="radio"][data-group="myGroup"]').removeAttr('checked');
            $(this).attr('checked', 'checked')
        });
    });

现在,这将为您提供您所描述的结果。现在是另一种选择(假设使用上面的模型),我们将另一个属性添加到PersonViewModel PrimaryName并将其设置为NameViewModel的ID(或主键)。使PersonViewModel看起来像。

public class PersonViewModel
{
    public PersonViewModel()
    {
        this.Names = new List<NameViewModel>();
    }

    public IList<NameViewModel> Names { get; set; }

    public int PrimaryName { get; set; }
}

然后你的标记为。

@Html.RadioButton("PrimaryName", name.ID, name.IsPrimary)
@Html.HiddenFor(x => x.Names[i].ID)

现在这也可以,但现在将PersonViewModel的“PrimaryName”设置为已检查的NameViewModel的ID。但是,由于我们没有将该值传回,因此您的NameViewModel将会忽略帖子上的IsPrimary值。要做到这两点,你必须连接这两个选项的组合。

希望这可以帮助您找到正确的方向。任何一种方法(或其他方法)都应该有用。

答案 1 :(得分:1)

不需要任何JavaScript。由于Primary是所有名称的公共属性,因此请更改ViewModels,如下所示:

  

的ViewModels

public class NameViewModel
{
    public int Id { get; set; }
    [Required]
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    [Required]
    public string LastName { get; set; }
    // other properties
    //...
}

public class PersonViewModel
{
    public IList<NameViewModel> Names { get; set; }
    [Required]
    public int? Primary { get; set; }
    // other properties
    //...
}
  

控制器

public ActionResult Index()
{
    var viewModel = new PersonViewModel
    {
        Names = new List<NameViewModel>
        {
            new NameViewModel {Id = 1, FirstName = "Stephen", MiddleName = "M", LastName = "Abney"},
            new NameViewModel {Id = 2, FirstName = "Jim", LastName = "Beam"}
        }
    };
    return View(viewModel);
}

[HttpPost]
public ActionResult Index(PersonViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        NameViewModel primaryName = viewModel.Names.SingleOrDefault(m => m.Id == viewModel.Primary);
        // save the data
    }
    return View(viewModel);
}
  

查看

@model PersonViewModel
...
@using (Html.BeginForm())
{
    <div>
        <table>
            <tbody>
                @for (int i = 0; i < Model.Names.Count; i++)
                {
                    <tr>
                        <td>
                            @Html.EditorFor(m => m.Names[i].FirstName)
                            @Html.ValidationMessageFor(m => m.Names[i].FirstName)
                        </td>
                        <td>
                            @Html.EditorFor(m => m.Names[i].MiddleName)
                            @Html.ValidationMessageFor(m => m.Names[i].MiddleName)
                        </td>
                        <td>
                            @Html.EditorFor(m => m.Names[i].LastName)
                            @Html.ValidationMessageFor(m => m.Names[i].LastName)
                        </td>
                        <td>
                            @Html.HiddenFor(m => m.Names[i].Id)
                            @Html.RadioButtonFor(m => m.Primary, Model.Names[i].Id, new { id = "Primary_" + i })
                        </td>
                    </tr>
                }
            </tbody>
        </table>
    </div>
    <div>
        @Html.ValidationMessageFor(m => m.Primary)
    </div>
    <div>
        <input type="submit" value="Save" />
    </div>
}

当然我简化了一点,但我认为你明白了。