1

全部,

我已经阅读了很多关于 Checkboxes 和 ASP.MVC 的帖子,但我并没有那么聪明。

我的场景:

我有一个强类型视图,我将汇总对象的集合传递给视图以在 for-each 中呈现。此摘要对象包含基于唯一 ID 的标签数据。我还在行中添加了一个复选框,因此可以通过以下方式进行:

<td>
    <%= Html.CheckBox("markedItem", Model.MarkedItem, new { TrackedItemId = Model.Id })%>
</td>

当我执行 POST 以获取提交的结果时,我的操作方法会取回强类型的 ViewModel,但我用于创建列表的原始摘要对象未填充。

好吧,这很烦人,但我能理解为什么,所以我会忍受它。

然后我要做的是向我的 ViewModel 添加一个名为“MarkedItem”的新属性,它是一个字符串集合。

在回发时,如果复选框已更改,则此标记的项目将填充之前和之后的状态,但没有告诉我它们用于哪个键。澄清一下,如果我发送这个

  • TrackedItemId = A,值 = 假
  • TrackedItemId = B,值 = true
  • TrackedItemId = C,值 = 假

并将页面设置为此:

  • TrackedItemId = A,值 = true
  • TrackedItemId = B,值 = true
  • TrackedItemId = C,值 = 假

我会收回这个:

  • 标记项[0] = 真
  • 标记项[1] = 假
  • 标记项[2] = 真
  • 标记项 [3] = 假

换句话说,[0] 是新值,[1] 是旧值,[2] 和 [3] 表示未更改的值。

我的问题是:

  1. 这是正确的 - 我以这种方式得到前后?有没有办法只发送最新的值?
  2. 如何获取已添加的自定义属性 (TrackedItemId),以便为返回的字符串数组添加含义?

到目前为止,我喜欢 MVC,但它不能处理像这样简单的东西真的很令人困惑。我也是一个 javascript 菜鸟,所以我真的希望这不是答案,因为我想在我的自定义视图模型中返回数据。

请让任何解释/建议简单:)

4

2 回答 2

0

好的,我想出了一个技巧 - 我真的很讨厌我必须这样做,但我没有看到另一种解决方法,我相信它会在某个时候崩溃。

我已经通过自己的 ModelBinder 实现了一些其他问题(例如作为属性的类),因此已经将其扩展为包含此代码。我们所有的钥匙都使用 Guid。

如果下面有任何替代方案,请告诉我。

html

<%= Html.CheckBox("markedItem" + Model.Id, false)%>

C#

(GuidLength 是一个 const int = 36,Left 和 Right 是我们自己的字符串扩展)

//Correct checkbox values - pull all the values back from the context that might be from a checkbox. If we can parse a Guid then we assume
//its a checkbox value and attempt to match up the model. This assumes the model will be expecting a dictionary to receive the key and 
//boolean value and deals with several sets of checkboxes in the same page

//TODO: Model Validation - I don't think validation will be fired by this. Need to reapply model validation after properties have been set?    
Dictionary<string, Dictionary<Guid, bool>> checkBoxItems = new Dictionary<string, Dictionary<Guid, bool>>();

foreach (var item in bindingContext.ValueProvider.Where(k => k.Key.Length > GuidLength))
{
    Regex guidRegEx = new Regex(@"^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$");
        if (guidRegEx.IsMatch(item.Key.Right(GuidLength)))
        {
            Guid entityKey = new Guid(item.Key.Right(GuidLength));
            string modelKey = item.Key.Left(item.Key.Length - GuidLength);

            Dictionary<Guid, bool> checkedValues = null;
            if (!checkBoxItems.TryGetValue(modelKey, out checkedValues))
            {
                checkedValues = new Dictionary<Guid, bool>();
                checkBoxItems.Add(modelKey, checkedValues);
            }
        //The assumption is that we will always get 1 or 2 values. 1 means the contents have not changed, 2 means the contents have changed
        //and, so far, the first position has always contained the latest value
            checkedValues.Add(entityKey, Convert.ToBoolean(((string[])item.Value.RawValue).First()));
        }
}

foreach (var item in checkBoxItems)
{
    PropertyInfo info = model.GetType().GetProperty(item.Key,
            BindingFlags.IgnoreCase |
            BindingFlags.Public |
            BindingFlags.Instance);

        info.SetValue(model, item.Value, null); 
}
于 2010-02-08T19:01:35.513 回答
0
<p> 
<label> 
   Select project members:</label> 
<ul> 
    <% foreach (var user in this.Model.Users) 
       { %> 
    <li> 
        <%= this.Html.CheckBox("Member" + user.UserId, this.Model.Project.IsUserInMembers(user.UserId)) %><label 
            for="Member<%= user.UserId %>" class="inline"><%= user.Name%></label></li> 
    <% } %></ul> 

在控制器中:

    // update project members        
foreach (var key in collection.Keys)     
{        
        if (key.ToString().StartsWith("Member")) 
        { 
                int userId = int.Parse(key.ToString().Replace("Member", ""));    
                if (collection[key.ToString()].Contains("true"))         
                        this.ProjectRepository.AddMemberToProject(id, userId); 
                else 
                        this.ProjectRepository.DeleteMemberFromProject(id, userId); 
        } 
} 

感谢皮诺:)

于 2010-02-08T16:02:34.003 回答