我有一个视图模型巫婆包含重复的项目。 我将它们放置在通过EditorFor()方法,我的看法。
视图:
@model Models.MyModel
@using (Html.BeginForm(@Model.Action, @Model.Controller))
{
<div class="section" id="Terms">
@Html.EditorFor(m => m.Terms)
</div>
<input type="submit" value="Save" />
}
模型:
public class MyModel
{
public IEnumerable<Term> Terms { get; set; }
}
EditorTemplates \ Term.cshtml:
@model Models.Term
@if (Model != null)
{
<fieldset>
<legend>Term</legend>
@Html.HiddenFor(model => model.TermID)
<div class="editor-label">
@Html.LabelFor(model => model.Identifier)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Identifier)
@Html.ValidationMessageFor(model => model.Identifier)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Description)
@Html.ValidationMessageFor(model => model.Description)
</div>
</fieldset>
}
我希望能够动态地从列表视图中的添加/删除项目,像knockout.js这个例子,但我如何保存自动ID的MVC创建??:
http://knockoutjs.com/examples/cartEditor.html
下面是我这方面的要求:
我读过上的其他问题,我还没有发现这是一个真正明确的答案。 是knockout.js接受的方式做到这一点? 是否有与敲除和MVC这样做的任何的例子吗?
谢谢!
你想淘汰赛MVC http://knockoutmvc.com/CartEditor
您不必使用淘汰赛对于这一点,你真正需要的是JavaScript和验证,并创建/删除其映射到对事物的MVC侧宁静的控制器操作的动作。 你如何去实现那是你的。 淘汰赛很容易,但。
我发现这个职位嵌套集合模型中MVC3由贾勒特迈耶,谁不使用基因敲除和最大化代码重用的解决方案。
这既包括添加和删除的方法。 我会在这里勾勒add方法。
该模型
public class Person {
public string FirstName { get; set; }
public string LastName { get; set; }
public IList<PhoneNumber> PhoneNumbers { get; set; }
public IList<EmailAddress> EmailAddresses { get; set; }
public IList<Address> Addresses { get; set; }
}
查看
//New.cshtml:
@using (Html.BeginForm("New", "Person", FormMethod.Post))
{
@Html.EditorForModel()
<p>
<button type="submit">
Create Person
</button>
</p>
}
//Person.cshtml:
@Html.AntiForgeryToken()
@Html.HiddenFor(x => x.Id)
<p>
<label>First Name</label>
@Html.TextBoxFor(x => x.FirstName)
</p>
<p>
<label>Last Name</label>
@Html.TextBoxFor(x => x.LastName)
</p>
<div id="phoneNumbers">
@Html.EditorFor(x => x.PhoneNumbers)
</div>
<p>
@Html.LinkToAddNestedForm("Add Phone Number", "#phoneNumbers", ".phoneNumber", "PhoneNumbers", typeof(PhoneNumber))
</p>
//PhoneNumber.cshtml:
<div class="phoneNumber">
<p>
<label>Telephone Number</label>
@Html.TextBoxFor(x => x.Number)
</p>
<br/>
</div>
帮手
/// <param name="linkText">Text for Link</param>
/// <param name="containerElement">where this block will be inserted in the HTML using a jQuery append method</param>
/// <param name="counterElement">name of the class inserting, used for counting the number of items on the form</param>
/// <param name="collectionProperty">the prefix that needs to be added to the generated HTML elements</param>
/// <param name="nestedType">The type of the class you're inserting</param>
public static IHtmlString LinkToAddNestedForm<TModel>(this HtmlHelper<TModel> htmlHelper, string linkText,
string containerElement, string counterElement, string collectionProperty, Type nestedType)
{
var ticks = DateTime.UtcNow.Ticks;
var nestedObject = Activator.CreateInstance(nestedType);
var partial = htmlHelper.EditorFor(x => nestedObject).ToHtmlString().JsEncode();
partial = partial.Replace("id=\\\"nestedObject", "id=\\\"" + collectionProperty + "_" + ticks + "_");
partial = partial.Replace("name=\\\"nestedObject", "name=\\\"" + collectionProperty + "[" + ticks + "]");
var js = string.Format("javascript:addNestedForm('{0}','{1}','{2}','{3}');return false;", containerElement,
counterElement, ticks, partial);
TagBuilder tb = new TagBuilder("a");
tb.Attributes.Add("href", "#");
tb.Attributes.Add("onclick", js);
tb.InnerHtml = linkText;
var tag = tb.ToString(TagRenderMode.Normal);
return MvcHtmlString.Create(tag);
}
private static string JsEncode(this string s)
{
if (string.IsNullOrEmpty(s)) return "";
int i;
int len = s.Length;
StringBuilder sb = new StringBuilder(len + 4);
string t;
for (i = 0; i < len; i += 1)
{
char c = s[i];
switch (c)
{
case '>':
case '"':
case '\\':
sb.Append('\\');
sb.Append(c);
break;
case '\b':
sb.Append("\\b");
break;
case '\t':
sb.Append("\\t");
break;
case '\n':
//sb.Append("\\n");
break;
case '\f':
sb.Append("\\f");
break;
case '\r':
//sb.Append("\\r");
break;
default:
if (c < ' ')
{
//t = "000" + Integer.toHexString(c);
string tmp = new string(c, 1);
t = "000" + int.Parse(tmp, System.Globalization.NumberStyles.HexNumber);
sb.Append("\\u" + t.Substring(t.Length - 4));
}
else
{
sb.Append(c);
}
break;
}
}
return sb.ToString();
}
使用Javascript
//since the html helper can change the text of the item inserted but not the index,
//this replaces the 'ticks' with the correct naming for the collection of properties
function addNestedForm(container, counter, ticks, content) {
var nextIndex = $(counter).length;
var pattern = new RegExp(ticks, "gi");
content = content.replace(pattern, nextIndex);
$(container).append(content);
}
你需要做以下几点:
- 发送模式控制器和渲染一个可编辑的字段项。
- 你问用户提交本或点击添加添加更多条件。
- 如果用户点击添加您创建现有油田的副本并清空他们或什么,使他们能够创造新的。
- 当用户提交您发回给接受条款的阵列行动,并把它添加到数据库或什么不是。 或者你可以使用AJAX像在上面的例子中或者从这个例子中你可以看到它向服务器发送的是JSON数组对象,而不是与命名的元素构成。
- 你可以处理他们,因为他们获得创建或者您可以处理他们提交。
取决于你的应用,以及使淘汰赛只是帮助你在客户端的第3步要在其中创建从旧版本新。 你可以起诉该JQuery的模板以及和json2旧的浏览器支持连载。
所有你需要了解的是,一旦你在客户端您发送您的模型在这里一次,所以不要对服务器端的担心。 无论在客户端,你可以建立在一个时间saveTerm作用,这retruns JSON与单词ID等信息被发送给任何一个模式,或者你可以返回saveTerm的集合作为一个JSON数组,它会正常工作。
如果你正在考虑发送回发一个数组,而不是阿贾克斯只是不停的形式元素名称相同,且重复的项输入字段和送过来。 因为它与JSON时MVC将它们映射到项的数组。