将复选框绑定到局部视图中的“列表”

本文关键字:列表 视图 复选框 绑定 局部 | 更新日期: 2023-09-27 17:59:27

我有一个CreateViewModel

public class CreateViewModel
{
  public AttributesViewModel AttributesInfo { get; set; }
}

AttributesViewModel被发送到部分视图。

public class AttributesViewModel
{
  public AttributesViewModel()
  {
    ChosenAttributes = new List<int>();
  }
  public List<Attributes> Attributes { get; set; }
  public List<int> ChosenAttributes { get; set; }
}

属性列表在局部视图中输出。每个都有一个复选框。

foreach (var attribute in Model.Attributes)
{
  <input type="checkbox" name="ChosenAttributes" value="@attribute.ID" /> @Attribute.Name
}

当我发布CreateViewModel时,即使我选中了一些框,AttributesInfo.ChosenAttributes也总是空的。如何正确命名每个复选框,使其绑定到所选属性列表?

我的解决方案

我采纳了Stephen Muecke的建议,做双向装订。因此,我创建了一个CheckboxInfo类,其中包含Value、Text和IsChecked。我为它创建了一个编辑器模板:

@model Project.CheckboxInfo
@Html.HiddenFor(model => model.Text)
@Html.HiddenFor(model => model.Value)
@Html.CheckBoxFor(model => model.IsChecked)&nbsp;@Model.Text

一个巨大的警告。为了使其正常工作,我必须为AttributesViewModel类创建一个EditorTemplate。如果没有它,在发布CreateViewModel时,它将无法将复选框链接到AttributesInfo。

将复选框绑定到局部视图中的“列表”

您将复选框命名为name="ChosenAttributes",但CreateViewModel不包含名为ChosenAttributes的属性(只有一个名为AttributesInfo)。你可以使用来完成这项工作

<input type="checkbox" name="AttributesInfo.ChosenAttributes" value="@attribute.ID" /> @Attribute.Name

但正确的方法是使用一个包含布尔属性(比如bool IsSelected)的适当视图模型,并使用强类型帮助器在for循环中绑定到您的属性,或者使用自定义EditorTemplate,以便您的控件是正确的名称,并获得双向模型绑定。

我也有类似的场景,但我就是这样做的。解决方案并不完美,所以如果我遗漏了一些内容,请原谅,但你应该能够理解。我也试图简化您的解决方案:)

我将Attribute类名更改为CustomerAttribute,并将其重命名为任何您喜欢的名称,使用单数名称,而不是复数名称。在你的CustomerAttribute类中添加一个属性,可以随意命名,我称之为IsChange

public class CustomerAttribute
{
     public bool IsChange { get; set; }
     // The rest stays the same as what you have it in your Attributes class
     public string Name { get; set; }  // I'm assuming you have a name property
}

删除你的AttributesViewModel类,你其实并不需要它,我喜欢简单。

CreateViewModel类修改为如下所示:

public class CreateViewModel
{
     public CreateViewModel()
     {
          CustomerAttributes = new List<CustomerAttribute>();
     }
     public List<CustomerAttribute> CustomerAttributes { get; set; }
}

你的控制器看起来像这样:

public ActionResult Create()
{
     CreateViewModel model = new CreateViewModel();
     // Populate your customer attributes
     return View(model);
}

你的控制器后操作方法看起来像这样:

[HttpPost]
public ActionResult Create(CreateViewModel model)
{
     // Do whatever you need to do
}

在你看来,你会有这样的东西:

<table>
     <tbody>
          @for (int i = 0; i < Model.CustomerAttributes.Count(); i++)
          {
               <tr>
                    <td>@Html.DisplayFor(x => x.CustomerAttributes[i].Name)</td>
                    <td>@Html.CheckBoxFor(x => x.CustomerAttributes[i].IsChange)</td>
               </tr>
          }
     <tbody>
</table>

创建一个示例应用程序,尝试上面的代码,看看它是否适合你。