【问题标题】:How to find the Checked Status of All Checkboxes如何查找所有复选框的选中状态
【发布时间】:2010-05-27 14:07:56
【问题描述】:

这是我的问题。我有一个向用户显示的模型列表。左侧是每个模型的复选框,表示用户想要选择这个模型(在这种情况下,我们正在构建用户可以添加到他们的购物车中的产品)。该模型没有被选择的概念……它严格包含有关产品的信息。

在完成之后,我与其他一些开发人员进行了交谈,我能想到的最好的方法是获取表单集合和字符串解析键值以确定复选框是否被选中。这似乎并不理想。我在想会有更强烈的约束,但我想不出一种方法来做到这一点。

我尝试创建另一个模型,该模型具有一个布尔属性来表示被检查和模型的一个属性,并将该模型类型的列表传递给视图,并在接受新模型列表的控制器上创建 ActionResult /检查属性,但它返回 null。我是不是想得太像网络表单了,应该继续解析复选框值吗?

这是我为将模型包装在集合中所做的:


public class SelectableCollection[T] : IList[T] {}
public class SelectableTrack{
  public bool IsChecked{get;set;}
  public bool CurrentTrack{get;set;}
}

对于视图,我继承自


ViewPage[SelectableCollection[SelectableTrack]]

对于控制器,我将其作为 ActionResult:


[HttpPost]
        public ActionResult SelectTracks(SelectableCollection sc) {

            return new EmptyResult();
        }

但是当我在 ActionResult 内部中断时,集合为空。没有通过的任何原因?

【问题讨论】:

  • 最好问一个不同的问题,而不是完全重新措辞这个问题,以便以前的答案仍然相关......

标签: c# asp.net-mvc


【解决方案1】:

这是 ViewModel 很有用的情况。您需要能够表示“选定”项目,这不是模型的一部分,但您可以将其添加到 ViewModel。 ViewModel 旨在提供所有视图所需的信息,包括一些可能不属于模型的信息。

这是一个想法:是否可以将您的项目“包装”在一个表示选择的集合中?我在想SelectableCollection<T> 之类的东西(这可能源自ICollection<T> 或其他一些通用集合类型。)您可以将其添加到您的ViewModel 并将您的复选框绑定到它们。

【讨论】:

    【解决方案2】:

    在您的情况下,我将添加一个 ViewModel 以“选择”的概念扩展您的模型。这将允许您使用 MVC 的模型绑定技术来避免在表单集合中进行挖掘。

    在我发现 AutoMapper 之前,我非常不愿意加入 ViewModel 潮流。现在我有了 AutoMapper,我可以根据我的应用需要随意制作尽可能多的 ViewModel,并且可以轻松地将我的 ViewModel 映射回我的 (DTO) 模型以实现持久性。

    此外,WRT ASP.NET MVC 复选框,您最好熟悉一下如何处理复选框的一些怪癖。请参阅this question 了解更多详情。

    我个人使用此方法从使用复选框的模型绑定器中的 bindingContext 获取布尔值:

        public static bool? GetBool(ModelBindingContext bindingContext, string key)
        {
            var str = GetStr(bindingContext, key);
            bool tmp;
    
            if (string.IsNullOrEmpty(str))
                return null;
    
            str = str.ToLower().Trim();
    
            if (bool.TryParse(str, out tmp))
                return tmp;
    
            if (string.Compare(str, "no") == 0)
                return false;
    
            if (string.Compare(str, "yes") == 0)
                return true;
    
            if (string.Compare(str, "true,false") == 0)
                return true;
    
            return null;
        }
        public static string GetStr(ModelBindingContext bindingContext, string key)
        {
            if (string.IsNullOrEmpty(key))
                return null;
    
            var valueResult = bindingContext
                .ValueProvider
                .GetValue(bindingContext.ModelName + "." + key);
    
            if (valueResult == null && bindingContext.FallbackToEmptyPrefix)
                valueResult = bindingContext.ValueProvider.GetValue(key);
    
            return valueResult != null ? valueResult.AttemptedValue : null;
        }
    

    【讨论】:

      【解决方案3】:

      因为<%= Html.CheckBox() %> 为每个复选框呈现<input name="yourName" type="hidden" value="false" /> 以跟踪未选中的框,所以我使用以下解决方案:

      控制器

      public ActionResult MyAction([Bind(Prefix = "CheckBox")] Dictionary<int, bool> myCheckBoxes)
      {
      }
      

      视图模型

      public List<CheckBox> MyCheckBoxes{ get; private set; }
      
      MyCheckBoxes = modelRepository.GetMyCheckBoxes(userID);
      

      存储库

      public List<CheckBox> GetMyCheckBoxes(userID)
      {        
          IDictionary<int, bool> selectedModels = new Dictionary<int, bool>();
          ModelRespository modelRespository = new ModelRespository();
      
          foreach (var model in modelRespository.GetUserSelectedModels(userID))
          {
              selectedModels.Add(model.ModelID);
          }
      
          return (from m in modelRespository.GetModels()
              select new CheckBox
              {
                  ID = m.ModelID.ToString(),
                  Text = m.Name,
                  Checked = selectedModels.ContainsKey(m.ID)
              }).ToList();
      }
      

      查看

      <% int i = 0; foreach (CheckBox c in Model.MyCheckBoxes)
         { %>
      <p>
          <%= Html.Hidden(String.Format("CheckBox[{0}].Key", i), yourModelID)%>
          <%= Html.CheckBox(String.Format("CheckBox[{0}].Value", i), c.Checked)%>        
      </p>
      <% i++; } %>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-05-08
        • 1970-01-01
        • 1970-01-01
        • 2014-12-08
        • 2010-11-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多