我是ASP.Net MVC(和razor)的新手,我有几个问题。
1)
我创建了一个HTML扩展来创建一个复选框列表,如下所示:
public static HtmlString CheckBoxList(this HtmlHelper htmlHelper, string name, List<InputItemInfo> ItemInfo)
{
if (String.IsNullOrEmpty(name))
throw new ArgumentException("The argument must have a value", "name");
if (ItemInfo == null)
throw new ArgumentNullException("ItemInfo");
if (ItemInfo.Count < 1)
throw new ArgumentException("The list must contain at least one value", "ItemInfo");
StringBuilder sb = new StringBuilder();
ItemInfo.Insert(0, new InputItemInfo("*", "Select All", ItemInfo.All(i => i.IsChecked)));
foreach (InputItemInfo info in ItemInfo)
{
TagBuilder builder = new TagBuilder("input");
if (info.IsChecked) builder.MergeAttribute("checked", "checked");
builder.MergeAttribute("type", "checkbox");
builder.MergeAttribute("value", info.Value);
builder.MergeAttribute("name", name);
builder.InnerHtml = info.DisplayText;
sb.Append(builder.ToString(TagRenderMode.Normal));
sb.Append("<br />");
}
return new HtmlString(sb.ToString());
}
我能够在我的视图中使用它,并在控制器中获取值,如下所示:
@model List<AppTest.Models.InputExtensionsViewModel>
@{
ViewBag.Title = "Check";
}
<h2>Check</h2>
@using (Html.BeginForm())
{
<table border="0" style="border:0px;">
<tr>
<td valign="top">
@Html.Partial("CheckBoxList", Model[0])
</td>
</tr>
</table>
<br />
<input type="submit" value="Go" />
}
<div style="font-weight:bolder">
@ViewData["data"]
</div>
控制器:
public ActionResult Check()
{
var model = new List<InputExtensionsViewModel>();
var model1 = new InputExtensionsViewModel
{
Title = "Facilities",
InputElementName = "facilities",
InputElements = // a list
};
model.Add(model1);
return View(model);
}
[HttpPost]
public ActionResult Check(string[] facilities)
{
...
}
模型是:
public class InputExtensionsViewModel
{
public string Title { get; set; }
public string InputElementName { get; set; }
public List<InputItemInfo> InputElements { get; set; }
public void SetSelected(string[] items)
{
if (items == null)
return;
this.InputElements.ForEach(delegate(InputItemInfo info)
{
if (items.Contains(info.Value))
info.IsChecked = true;
});
}
}
我的问题是,有没有办法将数组项绑定到InputExtensionsViewModel模型中的属性?如果我只是将一个名为facility的属性添加到视图模型中,它不会自动绑定,我可以理解为什么,因为我在视图中没有绑定。但我似乎无法想出一种可以做到这一点的方法。
此复选框列表是一个用户控件,我只是想避免为我的操作方法使用太多string []数组。
[编辑] - 好的,我现在尝试的时候能做到这一点。不知道为什么它之前没有用。
2)而且,我正在检查替代方案,并在SO中找到了这个答案:
我能够复制这个,但我的问题是,如何将标签绑定到此复选框?我的标签是动态的,是模型的一部分,所以不能硬编码。我试图使用Html.LabelFor,但这不起作用。在编辑器模板中,如果我只是@ Model.Text,它将无法工作,并且在回复后将丢失,因为它未绑定到属性
我用谷歌搜索并找到了创建HTML助手的建议,这是我之前所做的(我的第一个问题就是这个)。
如果不清楚,请告诉我。我可以详细说明。任何意见都表示赞赏!
提前致谢!
答案 0 :(得分:2)
要回答第2部分,您可以轻松地将标签文本添加为属性,例如:
public class MyViewModel
{
public int Id { get; set; }
public bool IsChecked { get; set; }
public string Text { get; set; }
}
然后你的模板看起来就像这样:
@model AppName.Models.MyViewModel
@Html.HiddenFor(x => x.Id)
@Html.CheckBoxFor(x => x.IsChecked)
@Html.LabelFor(x => x.Text)
上述唯一的缺点是标签不会直接链接到复选框。您可以通过执行以下操作来完成此操作:CheckboxList in MVC3
根据重复使用的可能性,您可以像在第一部分中那样创建自己的HtmlHelper,并包含上面粘贴的URL中的建议。
答案 1 :(得分:2)
啊,我找到了解决方案!
1)如我的编辑所示 - 添加一个名称与模型类似的属性,并在[HttpPost]启用的操作方法中使用它可以正常工作。猜猜上次我错过了吸气鬼和安装者。
2)为此,在MyViewModel的编辑器模板中,我们只需要添加它(**和**,不用说,删除**!):
@model AppName.Models.MyViewModel
@Html.HiddenFor(x => x.Id)
@Html.CheckBoxFor(x => x.IsChecked) **@Model.Text
@Html.HiddenFor(x => x.Text)**
编辑:
我已更改此模板以执行更多操作。现在有一个标签控件,它通过jquery与复选框相关联,如下所示。
@model EncorPlusTest.Infrastructure.InputItemInfo
@Html.HiddenFor(model => model.Value)
@Html.CheckBoxFor(model => model.IsChecked) <label for="">@Model.Text</label>
@Html.HiddenFor(model => model.Text)
<br />
然后在jquery:
$('input:checkbox').each(function () {
var lbl = $(this).next('input:hidden').next('label');
var forID = $(this).attr('id');
$(lbl).attr('for', forID);
});
希望它对别人有帮助!
答案 2 :(得分:0)
你没有jQuery来解决这个问题。如果用标签包装输入,则会得到相同的行为。
顺便说一句,另一个选项是HTML Helper而不是编辑器模板。看看这个:
public static class HtmlHelperExtensions
{
#region CheckBoxList
public static MvcHtmlString CheckBoxList(this HtmlHelper htmlHelper, string name, List<SelectListItem> listInfo)
{
return htmlHelper.CheckBoxList(name, listInfo, ((IDictionary<string, object>)null));
}
public static MvcHtmlString CheckBoxList(this HtmlHelper htmlHelper, string name, List<SelectListItem> listInfo, object htmlAttributes)
{
return htmlHelper.CheckBoxList(name, listInfo, ((IDictionary<string, object>)new RouteValueDictionary(htmlAttributes)));
}
public static MvcHtmlString CheckBoxList(this HtmlHelper htmlHelper, string name, List<SelectListItem> selectListItems, IDictionary<string, object> htmlAttributes)
{
// Verify arguments
if (String.IsNullOrEmpty(name))
throw new ArgumentNullException("name", "Name cannot be null");
if (selectListItems == null)
throw new ArgumentNullException("selectList", "Select list cannot be null");
if (selectListItems.Count() < 1)
throw new ArgumentException("Select list must contain at least one value", "selectList");
// Define items
StringBuilder items = new StringBuilder();
int index = 0;
// Loop through items)
foreach (SelectListItem i in selectListItems)
{
// hidden value
TagBuilder hiddenValue = new TagBuilder("input");
hiddenValue.MergeAttribute("type", "hidden");
hiddenValue.MergeAttribute("value", i.Value);
hiddenValue.MergeAttribute("id", string.Format("{0}_{1}__Value", name, index));
hiddenValue.MergeAttribute("name", string.Format("{0}[{1}].Value", name, index));
// check box
TagBuilder checkbox = new TagBuilder("input");
if (i.Selected)
checkbox.MergeAttribute("checked", "checked");
checkbox.MergeAttribute("id", string.Format("{0}_{1}__Selected", name, index));
checkbox.MergeAttribute("name", string.Format("{0}[{1}].Selected", name, index));
checkbox.MergeAttribute("type", "checkbox");
checkbox.MergeAttribute("value", "true");
// wrapper label
TagBuilder wrapperLabel = new TagBuilder("label");
wrapperLabel.InnerHtml = checkbox.ToString(TagRenderMode.SelfClosing);
wrapperLabel.InnerHtml += i.Text;
// hidden selected
TagBuilder hiddenSelected = new TagBuilder("input");
hiddenSelected.MergeAttribute("type", "hidden");
hiddenSelected.MergeAttribute("value", i.Selected.ToString().ToLower());
hiddenSelected.MergeAttribute("name", string.Format("{0}[{1}].Selected", name, index));
// label for checkbox
TagBuilder checkBoxLabel = new TagBuilder("label");
checkBoxLabel.MergeAttribute("for", checkbox.Attributes["id"]);
checkBoxLabel.MergeAttribute("id", string.Format("{0}_{1}__Text", name, index));
checkBoxLabel.MergeAttribute("name", string.Format("{0}[{1}].Text", name, index));
// hidden text
TagBuilder hiddenText = new TagBuilder("input");
hiddenText.MergeAttribute("type", "hidden");
hiddenText.MergeAttribute("value", i.Text);
hiddenText.MergeAttribute("id", string.Format("{0}_{1}__Text", name, index));
hiddenText.MergeAttribute("name", string.Format("{0}[{1}].Text", name, index));
// Add item
items.AppendLine(hiddenValue.ToString(TagRenderMode.SelfClosing));
items.AppendLine(wrapperLabel.ToString(TagRenderMode.Normal));
items.Append(hiddenSelected.ToString(TagRenderMode.SelfClosing));
items.AppendLine(hiddenText.ToString(TagRenderMode.SelfClosing));
items.AppendLine();
index++;
}
return MvcHtmlString.Create(items.ToString());
}
public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
var name = ExpressionHelper.GetExpressionText(expression);
var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
return CheckBoxList(htmlHelper, name, metadata.Model as List<SelectListItem>);
}
#endregion
}