所有
我已经阅读了很多关于Checkboxes和ASP.MVC的帖子,但我并没有那么明智。
我的情景:
我有一个强类型视图,我将一组摘要对象传递给视图,以便在for-each中进行渲染。此摘要对象包含基于唯一ID的标签数据。我还在行中添加了一个复选框,所以请通过以下方式添加:
<td>
<%= Html.CheckBox("markedItem", Model.MarkedItem, new { TrackedItemId = Model.Id })%>
</td>
当我执行POST以获取提交的结果时,我的action方法返回强类型的ViewModel,但是我没有填充用于创建列表的原始摘要对象。
好的,这很烦人,但我明白为什么所以我会忍受它。
我接下来要为我的ViewModel添加一个名为“MarkedItem”的新属性,这是一个字符串集合。
在回发时,如果复选框已更改,则此标记项目将填充之前和之后状态,但没有任何内容可以告诉我它们用于哪个键。只是为了澄清,如果我发送这个
并将页面设置为:
我会回来的:
换句话说,[0]是新值,[1]是旧值,[2]和[3]表示未更改的值。
我的问题是:
到目前为止,我喜欢MVC,但它不处理像这样的简单的东西真的很混乱。我也是一个javascript noob,所以我真的希望这不是答案,因为我想在我的自定义视图模型中返回数据。
请简单解释/建议:)
答案 0 :(得分: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);
}
}
感谢Pino:)
答案 1 :(得分: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);
}