2011-04-18 19 views
5

मैं फिल Haackमॉडल एमवीसी 3 में गैर अनुक्रमिक सूचकांक के साथ एक सूची में बाध्यकारी?

से http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx पर जानकारी अनुसरण कर रहा हूं वह गैर अनुक्रमिक सूचकांक बारे में बात करती है: जब आप TextBoxFor साथ बंधन मॉडल का उपयोग

<form method="post" action="/Home/Create"> 

<input type="hidden" name="products.Index" value="cold" /> 
<input type="text" name="products[cold].Name" value="Beer" /> 
<input type="text" name="products[cold].Price" value="7.32" /> 

<input type="hidden" name="products.Index" value="123" /> 
<input type="text" name="products[123].Name" value="Chips" /> 
<input type="text" name="products[123].Price" value="2.23" /> 

<input type="hidden" name="products.Index" value="caliente" /> 
<input type="text" name="products[caliente].Name" value="Salsa" /> 
<input type="text" name="products[caliente].Price" value="1.23" /> 

<input type="submit" /> 
</form> 

MVC3 में यह संभव है?

@Html.TextBoxFor(m => m[i].Value) 

यदि यह संभव नहीं है, किसी और उनके कुछ भी मैं कर सकता हूँ अगर मेरे सूचकांक अनुक्रमिक नहीं होगा:
इस तरह sequentiel सूचकांक के साथ यह करने के लिए है?

+0

यह अभी भी मदों की एक अनुक्रमिक सूची है। वैकल्पिक इंडेक्सिंग एचटीएमएल उत्पन्न करने से परे आपको जो हासिल करने की कोशिश कर रहे हैं, उसके बारे में आपको अधिक संदर्भ प्रदान करने की आवश्यकता है। क्या आप संग्रह आइटम रीडरिंग, अतिरिक्त और निष्कासन को कार्यान्वित करने की कोशिश कर रहे हैं, आपको इस वाक्यविन्यास की आवश्यकता नहीं है? –

उत्तर

1

एएफएआई समझता है कि अनुक्रमिक सूचकांक तकनीक को प्रत्येक इंडेक्स मूल्य के लिए छिपे हुए फ़ील्ड जोड़ने की आवश्यकता होगी। मुझे पूरा यकीन है कि Html.TextBoxFor सहायक स्वयं कोई अतिरिक्त छिपे हुए फ़ील्ड उत्पन्न नहीं करता है। शायद आप छिपे हुए फ़ील्ड को गैर अनुक्रमिक सूचकांक के साथ मैन्युअल रूप से जोड़कर इसे प्राप्त कर सकते हैं।

0

मैंने कोशिश की और मैं इसे टेक्स्टबॉक्स के साथ काम करने के लिए नहीं मिला। मैंने टेक्स्टबॉक्स का इस्तेमाल किया और नाम निर्दिष्ट किया।

<form method="post" action="/Home/Create"> 
@{var index = Guid.NewGuid();} 
@Html.Textbox("products["+index +"].Name",Beer) 
@Html.Textbox("products["+index +"].Price",7.32) 
. 
. 
. 
<input type="submit" /> 
</form> 

आपको एमवीसी 3.0 के लिए एक छिपी हुई इंडेक्स की आवश्यकता नहीं है।

मुझे बताएं कि यह काम नहीं करता है, मेरे पास ऐसा करने का एक तरीका है, मैं इसे अपने सिर के शीर्ष से ले रहा हूं।

+0

मैं इसे काम करने के लिए कोशिश कर रहा हूं जैसा कि आपने इंडेक्स के लिए छिपे हुए इनपुट का उपयोग किए बिना उल्लेख किया है और मैं इसे काम करने के लिए काफी कुछ नहीं कर सकता। क्या आपके पास एक कामकाजी उदाहरण है? –

0

अपने विचार से गड़बड़ न करने के लिए, मुझे यह करने का सबसे आसान तरीका इस एक्सटेंशन का पालन करना है: BeginCollectionItem

पूरा परियोजना यहाँ है: https://github.com/danludwig/BeginCollectionItem

लेकिन AFAIK आप केवल इस वर्ग की जरूरत है:

public static class HtmlPrefixScopeExtensions 
    { 
     private const string idsToReuseKey = "__htmlPrefixScopeExtensions_IdsToReuse_"; 

     public static IDisposable BeginCollectionItem(this HtmlHelper html, string collectionName) 
     { 
      var idsToReuse = GetIdsToReuse(html.ViewContext.HttpContext, collectionName); 
      string itemIndex = idsToReuse.Count > 0 ? idsToReuse.Dequeue() : Guid.NewGuid().ToString(); 

      // autocomplete="off" is needed to work around a very annoying Chrome behaviour whereby it reuses old values after the user clicks "Back", which causes the xyz.index and xyz[...] values to get out of sync. 
      html.ViewContext.Writer.WriteLine(string.Format("<input type=\"hidden\" name=\"{0}.index\" autocomplete=\"off\" value=\"{1}\" />", collectionName, html.Encode(itemIndex))); 

      return BeginHtmlFieldPrefixScope(html, string.Format("{0}[{1}]", collectionName, itemIndex)); 
     } 

     public static IDisposable BeginHtmlFieldPrefixScope(this HtmlHelper html, string htmlFieldPrefix) 
     { 
      return new HtmlFieldPrefixScope(html.ViewData.TemplateInfo, htmlFieldPrefix); 
     } 

     private static Queue<string> GetIdsToReuse(HttpContextBase httpContext, string collectionName) 
     { 
      // We need to use the same sequence of IDs following a server-side validation failure, 
      // otherwise the framework won't render the validation error messages next to each item. 
      string key = idsToReuseKey + collectionName; 
      var queue = (Queue<string>)httpContext.Items[key]; 
      if (queue == null) { 
       httpContext.Items[key] = queue = new Queue<string>(); 
       var previouslyUsedIds = httpContext.Request[collectionName + ".index"]; 
       if (!string.IsNullOrEmpty(previouslyUsedIds)) 
        foreach (string previouslyUsedId in previouslyUsedIds.Split(',')) 
         queue.Enqueue(previouslyUsedId); 
      } 
      return queue; 
     } 

     private class HtmlFieldPrefixScope : IDisposable 
     { 
      private readonly TemplateInfo templateInfo; 
      private readonly string previousHtmlFieldPrefix; 

      public HtmlFieldPrefixScope(TemplateInfo templateInfo, string htmlFieldPrefix) 
      { 
       this.templateInfo = templateInfo; 

       previousHtmlFieldPrefix = templateInfo.HtmlFieldPrefix; 
       templateInfo.HtmlFieldPrefix = htmlFieldPrefix; 
      } 

      public void Dispose() 
      { 
       templateInfo.HtmlFieldPrefix = previousHtmlFieldPrefix; 
      } 
     } 
    } 

कैसे अपने दृश्य में इसका उपयोग करना:

<form method="post" action="/Home/Create"> 
    @foreach (var item in Model.Products) {  
     @using (Html.BeginCollectionItem("Products")) 
     { 
      @Html.TextBoxFor(item => item.Name) 
      @Html.TextBoxFor(item => item.Price)    
     } 
    } 
     ... 
     ... 
</form> 

मैं इस बारे में सोच आपके विचारों में इंडेक्स के साथ गड़बड़ करने से क्लीनर है ... यहां वह पोस्ट है जो बताती है कि इसे कैसे चरणबद्ध करना है ईपी: http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/

Nuget पैकेज:http://www.nuget.org/packages/BeginCollectionItem/