2013-02-05 14 views
7

मेरे पास एक दृश्य मॉडल चुड़ैल में पुनरावृत्त आइटम हैं। मैं उन्हें EditorFor() विधि के माध्यम से अपने दृश्य में रखता हूं।एमवीसी 4 संपादक के लिए लाइन आइटम को गतिशील रूप से जोड़ने के लिए कैसे करें?

दृश्य:

@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 पर इस उदाहरण की तरह है, लेकिन मैं ऑटो आईडी के MVC ?? बनाता है कैसे बचाऊं में सक्षम:

http://knockoutjs.com/examples/cartEditor.html

यहाँ इस के लिए मेरे आवश्यकताओं: नई शर्तों

  • जोड़े
  • शर्तों
  • निकालें मान्य नई शर्तों विचारों
  • जोड़ रहे हैं कि

मैंने SO पर अन्य प्रश्न पढ़े हैं और मुझे इस पर एक वास्तविक निश्चित उत्तर नहीं मिला है। क्या यह करने के लिए स्वीकार्य तरीका knockout.js है? क्या नॉकआउट और एमवीसी के साथ ऐसा करने के कोई उदाहरण हैं?

धन्यवाद!

उत्तर

0

आप पीटकर MVC http://knockoutmvc.com/CartEditor

आप इस के लिए नॉकआउट उपयोग करने के लिए नहीं है, आप वास्तव में क्या जरूरत है सत्यापन के साथ जावास्क्रिप्ट है और बनाने/कार्रवाई से है जो चीजों की MVC तरफ शोकहारा नियंत्रक कार्यों पर नक्शा हटाना चाहते हैं। आप इसे लागू करने के बारे में कैसे जाते हैं जो आपके ऊपर है। नॉकआउट हालांकि यह आसान बनाता है।

+0

मैं यह कैसे काम करता है देखना हालांकि, यह वास्तव में यह नहीं दिखाता है कि इसे EditorFor() के साथ कैसे उपयोग किया जाए। क्या अब मुझे इसका इस्तेमाल करने की ज़रूरत नहीं है? यह उदाहरण इसे BeginForm() और पोस्ट विधि के भीतर नहीं दिखाता है, क्या यह मॉडल सही ढंग से बांधता है? –

0

आप निम्न कार्य करने की जरूरत है:

  1. अपने नियंत्रक करने के लिए एक मॉडल भेजें और कार्यकाल के लिए एक संपादन योग्य फ़ील्ड प्रस्तुत करना।
  2. आप उपयोगकर्ता को यह सबमिट करने के लिए कहते हैं या अधिक शर्तों को जोड़ने के लिए जोड़ें पर क्लिक करते हैं।
  3. यदि उपयोगकर्ता जोड़ने पर क्लिक करता है तो आप मौजूदा फ़ील्ड की एक प्रति बनाते हैं और उन्हें खाली करते हैं या जो भी वे नया बना सकते हैं।
  4. जब उपयोगकर्ता सबमिट करता है तो आप इसे वापस उस क्रिया पर भेजते हैं जो शर्तों की सरणी स्वीकार करता है और इसे डेटाबेस में जोड़ता है या नहीं। या आप उपरोक्त उदाहरण में या this example से AJAX का उपयोग कर सकते हैं, आप देख सकते हैं कि यह सर्वर पर क्या भेजता है जेसन सरणी ऑब्जेक्ट है और नामित तत्वों के साथ नहीं है।
  5. आप उन्हें बनाते समय संसाधित कर सकते हैं या आप उन्हें सबमिट करने पर संसाधित कर सकते हैं।

आपके आवेदन पर निर्भर करता है, इसलिए नॉकआउट केवल आपको चरण 3 के लिए क्लाइंट पर मदद कर रहा है जहां आप पुरानी प्रतिलिपि से नया बना रहे हैं। आप उस के लिए JQuery टेम्पलेट्स और पुराने ब्राउज़र समर्थन के साथ serialise करने के लिए json2 मुकदमा कर सकते हैं।

आपको यह समझने की आवश्यकता है कि एक बार जब आप क्लाइंट पर हों तो आपने एक बार यहां अपना मॉडल भेजा है, इसलिए सर्वर की तरफ चिंता न करें। जो कुछ भी आप क्लाइंट साइड पर बनाते हैं उसे सहेजने के लिए एक मॉडल को एक समय में भेजा जा सकता है। टर्म एक्शन जो टर्म आईडी और अन्य जानकारी के साथ जेसन को दोबारा हटा देता है या आप एक जेसन सरणी के रूप में saveTerm का संग्रह वापस कर सकते हैं और यह ठीक काम करेगा।

यदि आप पोस्टबैक पर एक सरणी भेजने की सोच रहे हैं और AJAX नहीं है तो फॉर्म तत्वों के नामों को समान रखें और डुप्लिकेट टर्म इनपुट फ़ील्ड रखें और भेजें। एमवीसी उन्हें जेसन के साथ शब्दों की एक सरणी के रूप में मैप करेगा।

1

मुझे यह पोस्ट 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); 
} 
+0

एक नेस्टेड फॉर्म जोड़ने से 'टिक्स' संपत्ति के लिए एक अद्वितीय मूल्य होने पर अत्यधिक निर्भर होता है जो धीमे कंप्यूटर पर नहीं हो सकता है। यह सुनिश्चित करने के लिए, आप या तो GUID का उपयोग कर सकते हैं या कुछ ऐसा कर सकते हैं: System.Threading.Thread.Sleep (1); लंबी ticks = DateTime.UtcNow.Ticks; –

संबंधित मुद्दे