3

这段代码:

Html.CheckBoxList(ViewData.TemplateInfo.HtmlFieldPrefix, myList)

产生这个标记:

<ul><li><input name="Header.h_dist_cd" type="checkbox" value="BD" />
        <span>BD - Dist BD Name</span></li>
    <li><input name="Header.h_dist_cd" type="checkbox" value="SS" />
        <span>SS - Dist SS Name</span></li>
    <li><input name="Header.h_dist_cd" type="checkbox" value="DS" />
        <span>DS - Dist DS Name</span></li>
    <li><input name="Header.h_dist_cd" type="checkbox" value="SW" />
        <span>SW - Dist SW Name </span></li>
</ul>

您可以检查多个选择。返回字符串参数Header.h_dist_cd仅包含第一个选择的值。我需要做什么才能获得其他检查值?

post 方法参数如下所示:

public ActionResult Edit(Header header)
4

3 回答 3

4

我假设 Html.CheckBoxList 是您的扩展,这是您生成的标记。

根据您显示的内容,需要检查两件事:

  1. 模型绑定器将寻找一个名为 Header 的对象,该对象具有要绑定的字符串属性 h_dist_cd。您的操作方法看起来像 Header 是根视图模型,而不是模型的子对象。
  2. 我不知道您如何处理清除复选框的情况。正常的技巧是渲染一个具有相同名称的隐藏字段。

也是一个笨蛋,但您想使用 'label for="..."' 以便他们可以单击文本以选中/取消选中和可访问性。

我发现使用扩展来解决这个问题很容易出错。您可能需要考虑使用子视图模型。它更适合MVC2的EditorFor模板系统。

这是我们系统中的一个示例...

在视图模型中,嵌入一个可重用的子模型......

[AtLeastOneRequired(ErrorMessage = "(required)")]
public MultiSelectModel Cofamilies { get; set; }

您可以使用 SelectListItem 的标准列表对其进行初始化...

MyViewModel(...)
{
  List<SelectListItem> initialSelections = ...from controller or domain layer...;
  Cofamilies = new MultiSelectModel(initialSelections);
  ...

MultiSelectModel 子模型。请注意对值的设置器覆盖...

public class MultiSelectModel : ICountable
{
  public MultiSelectModel(IEnumerable<SelectListItem> items)
  {
    Items = new List<SelectListItem>(items);
    _value = new List<string>(Items.Count);
  } 

  public int Count { get { return Items.Count(x => x.Selected); } } 
  public List<SelectListItem> Items { get; private set; }

  private void _Select()
  {
    for (int i = 0; i < Items.Count; i++)
      Items[i].Selected = Value[i] != "false";
  }

  public List<SelectListItem> SelectedItems
  {
    get { return Items.Where(x => x.Selected).ToList(); }
  } 

  private void _SetSelectedValues(IEnumerable<string> values)
  {
    foreach (var item in Items)
    {
      var tmp = item;
      item.Selected = values.Any(x => x == tmp.Value);
    }
  } 

  public List<string> SelectedValues
  {
    get { return SelectedItems.Select(x => x.Value).ToList(); }
    set { _SetSelectedValues(value); }
  } 

  public List<string> Value
  {
    get { return _value; }
    set { _value = value; _Select(); }
  }
  private List<string> _value; 
}

现在您可以将编辑器模板放在 Views/Shared/MultiSelectModel.ascx...

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<WebUI.Cofamilies.Models.Shared.MultiSelectModel>" %>

<div class="set">

<%=Html.LabelFor(model => model)%>

<ul>
  <% for (int i = 0; i < Model.Items.Count; i++)
  {
    var item = Model.Items[i];
    string name = ViewData.ModelMetadata.PropertyName + ".Value[" + i + "]";
    string id = ViewData.ModelMetadata.PropertyName + "_Value[" + i + "]";
    string selected = item.Selected ? "checked=\"checked\"" : "";
  %>
  <li>
    <input type="checkbox" name="<%= name %>" id="<%= id %>" <%= selected %> value="true" />
    <label for="<%= id %>"><%= item.Text %></label>
    <input type="hidden" name="<%= name %>" value="false" />
  </li>
  <% } %>
</ul>
<%= Html.ValidationMessageFor(model => model) %>

这种方法的两个优点:

  1. 您不必将项目列表与选择值分开处理。您可以将属性放在单个属性上(例如,AtLeastOneRequired 是我们系统中的自定义属性)

  2. 您将模型和视图(编辑器模板)分开。例如,我们有水平和垂直布局的复选框。您还可以将“多选”呈现为两个带有来回按钮的列表框、多选列表框等。

于 2010-07-30T08:21:17.363 回答
2

我认为您需要的是如何从用户选择的 CheckBoxList 中收集选定的值,这是我的解决方案:

1- 下载 Jquery.json.js 并将其添加到您的视图中作为参考:

2-我已经为所有复选框列表项添加了一个“.cssMyClass”,所以我通过它们的 css 类来获取值:

 <script type="text/javascript" >
       $(document).ready(function () {
           $("#btnSubmit").click(sendValues);
         });

     function populateValues()
     {
         var data = new Array();
         $('.myCssClas').each(function () {
             if ($(this).attr('checked')) {
                 var x = $(this).attr("value");
                 data.push(x);
             }
         }); 

         return data;
     }

     function sendValues() {
         var data = populateValues();
               $.ajax({
                   type: 'POST',
                   url: '@Url.Content("~/Home/Save")',
                   data: $.json.encode(data),
                   dataType: 'json',
                   contentType: 'application/json; charset=utf-8',
                   success: function () { alert("1"); }
               });

       } 



 </script>

3- 如您所见,我已将所有选定的值添加到数组中,并通过 ajax 将其传递给“主页”控制器的“保存”操作 4- 在控制器中,您可以通过添加数组作为参数来接收值:

 [HttpPost]
        public ActionResult Save(int[] val)
        {

我搜索了太多,但显然这是唯一的解决方案。如果您找到更好的解决方案,请告诉我。

于 2011-10-27T03:07:20.900 回答
1

当您有多个具有相同名称的项目时,您将使用逗号分隔它们的值

于 2010-07-30T09:05:03.470 回答