【问题标题】:Pass List of Checkboxes into View and Pull out IEnumerable [duplicate]将复选框列表传递到视图中并拉出 IEnumerable [重复]
【发布时间】:2015-06-15 00:45:54
【问题描述】:

我有一个将与用户关联的项目列表。这是一对多的关系。我希望将整个项目列表传递到视图中,以便他们可以从尚未与它们关联的项目中进行选择(并且还可以查看那些已经关联的项目)。我想从这些创建复选框。然后我想将选定的发送回控制器以进行关联。我怎样才能传入所有它们的列表,包括那些尚未关联的列表,并可靠地将它们传回以进行关联?

这是我首先尝试的方法,但很明显这不起作用,因为我将输入基于通过 AllItems 集合传入的项目,该集合与用户本身的项目没有任何联系。

<div id="item-list">
    @foreach (var item in Model.AllItems)
    {
        <div class="ui field">
            <div class="ui toggle checkbox">
                <input type="checkbox" id="item-@item.ItemID" name="Items" value="@item.Active" />
                <label for="item-@item.ItemID">@item.ItemName</label>
            </div>
        </div>
    }
</div>

【问题讨论】:

    标签: c# asp.net-mvc razor asp.net-mvc-5


    【解决方案1】:

    您不能使用foreach 循环绑定到集合。您也不应该手动生成您的 html,在这种情况下这将不起作用,因为未选中的复选框不会回发。始终使用强类型的 html 帮助程序,以便获得正确的 2 向模型绑定。

    您尚未指明您的模型是什么,但假设您有一个 User 并希望为该用户选择 Roles,然后创建视图模型来表示您希望在视图中显示的内容

    public class RoleVM
    {
      public int ID { get; set; }
      public string Name { get; set; }
      public bool IsSelected { get; set; }
    }
    public class UserVM
    {
      public UserVM()
      {
        Roles = new List<RoleVM>();
      }
      public int ID { get; set; }
      public string Name { get; set; }
      public List<RoleVM> Roles { get; set; }
    }
    

    在 GET 方法中

    public ActionResult Edit(int ID)
    {
      UserVM model = new UserVM();
      // Get you User based on the ID and map properties to the view model
      // including populating the Roles and setting their IsSelect property
      // based on existing roles
      return View(model);
    }
    

    查看

    @model UserVM
    @using(Html.BeginForm())
    {
      @Html.HiddenFor(m => m.ID)
      @Html.DisplayFor(m => m.Name)
      for(int i = 0; i < Model.Roles.Count; i++)
      {
        @Html.HiddenFor(m => m.Roles[i].ID)
        @Html.CheckBoxFor(m => m.Roles[i].IsSelected)
        @Html.LabelFor(m => m.Roles[i].IsSelected, Model.Roles[i].Name)
      }
      <input type"submit" />
    }
    

    然后在post方法中,你的模型会被绑定,你可以查看选择了哪些角色

    [HttpPost]
    public ActionResult Edit(UserVM model)
    {
      // Loop through model.Roles and check the IsSelected property
    }
    

    【讨论】:

    • 这实际上就像我最终做的事情(略有不同)。不过,我可能会根据您的建议进行一些调整。谢谢!
    【解决方案2】:

    看起来您不会动态删除复选框,这样可以更轻松地解决此问题。注意:如果您允许客户端或脚本从页面中动态删除复选框,则以下解决方案将无法按预期工作,因为索引将不再是连续的。

    MVC 模型绑定并非万无一失,因此有时您必须帮助它。模型绑定器知道它需要绑定到一个名为 Items 的属性,因为输入字段的名称是 Items,但它不知道 Items 是一个列表。因此,假设在您的控制器中,您有一个项目列表来建模绑定到名为 Items 的项目,您需要做的是帮助 MVC 识别您正在绑定到一个列表。为此,请指定列表的名称和索引。

    <div id="item-list">
        @for (var i = 0; i < Model.AllItems.Count; i++)
        {
            <div class="ui field">
                <div class="ui toggle checkbox">
                    <input type="checkbox" id="item-@Model.AllItems[i].ItemID" name="Items[@i]" value="@Model.AllItems[i].Active" />
                    <label for="item-@Model.AllItems[i].ItemID">@Model.AllItems[i].ItemName</label>
                </div>
            </div>
        }
    </div>
    

    这里的关键是:

    &lt;input type="checkbox" id="item-@Model.AllItems[i].ItemID" name="Items[@i]" value="@Model.AllItems[i].Active" /&gt;

    注意到项目[@i]?这告诉模型绑定器查找名为 Items 的属性并将此值绑定到 Items 的 i 处的索引。

    【讨论】:

    • 这行得通,因为它传入了项目索引,但每个项目的实际值为空。有没有办法传递有关对象的更多信息?
    • 那么我会假设您的 Items 列表不是布尔值列表吗?您处理该问题的方式是为模型绑定器提供更多信息。因此,如果您的项目列表中的对象有一个名为“Active”的属性,那么您的复选框的名称应该是 Items[@i].Active。然后,对于您要填充的任何其他字段,例如名称,您将有另一个名称为 Items[@i].Name 的输入。
    • 我想我很困惑 - 你是说我需要为一个复选框提供多个输入吗?如果我只想将项目 ID 传递回控制器怎么办?编辑:另外,为了检查复选框,您可能打算使用 checked 属性。
    • 你想绑定什么?如果您要绑定到 List,那么不,您只需要一个复选框,并且您不必担心为模型绑定器提供比 Items[@i] 更多的信息。如果您要绑定到 List 那么是的,您将需要多个输入字段来填写列表中每个对象的每个属性。原始类型(bool、int、char 等)不需要额外的点符号。对象类型可以。
    • 这不起作用,除非每个复选框都被选中。 DefaultModelBinder 要求集合索引器从零开始并且是连续的。由于未选中的复选框不会回发,因此第一个复选框未选中,则模型绑定将失败,Items 将为空。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多