मुझे यह पोस्ट Nested Collection Models in MVC3 जेरेट मेयर द्वारा मिला, जिसमे एक समाधान है जो नॉकआउट का उपयोग नहीं करता है और कोड पुन: उपयोग को अधिकतम करता है।
इसमें दोनों विधियों को जोड़ने और हटाने के लिए शामिल हैं। मैं यहां ऐड विधि की रूपरेखा तैयार करूंगा।
मॉडल
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();
}
जावास्क्रिप्ट
//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);
}
मैं यह कैसे काम करता है देखना हालांकि, यह वास्तव में यह नहीं दिखाता है कि इसे EditorFor() के साथ कैसे उपयोग किया जाए। क्या अब मुझे इसका इस्तेमाल करने की ज़रूरत नहीं है? यह उदाहरण इसे BeginForm() और पोस्ट विधि के भीतर नहीं दिखाता है, क्या यह मॉडल सही ढंग से बांधता है? –