2011-12-19 18 views
5

मैं स्टीव सैंडर्सन के BeginCollectionItem सहायक का उपयोग कर रहा हूं और एक समस्या में भाग गया। मेरे पास एक ऐसा फॉर्म है जिसमें असीमित इनाम फ़ील्ड जोड़ने का विकल्प है। मैं अपने सहायक का उपयोग कर रहा हूं क्योंकि इस क्षेत्र को उत्पन्न करने के तरीके के साथ इस समस्या को हल किया गया है और फ़ॉर्म को जमा होने पर इसे बाध्य करने के बारे में चिंता करने की आवश्यकता नहीं है।स्टीव सैंडर्सन की BeginCollectionItem सहायक सही ढंग से बाध्य नहीं होगा

मेरे पास इस रूप में कुछ चेकबॉक्स हैं जो अज्ञात राशि है। पुरस्कारों के विपरीत इस के साथ अंतर अज्ञात राशि डेटाबेस कॉल के बाद जानी जाएगी और जब कोड को देखने के लिए जाना जाता है तब तक जाना जाएगा।

तो मेरी कोड इस

public class FrmVm 
    { 
     public Guid Id { get; set; } 
     public string Name { get; set; } 
     public bool Active { get; set; } 

     public IList<WarrantyFeaturesVm> WarrantyFeaturesVm { get; set; } // this is the checkbox ones. 
     public IList<RewardVms> RewardVms { get; set; } // this is the dyanmic one that I needed the helper for 

     public CbCreditCardFrmVm() 
     { 
      Active = true; 
      WarrantyFeaturesVm = new List<WarrantyFeaturesVm>(); 
      RewardVms = new List<RewardVms>(); 
     } 
    } 


    // view 

    @foreach (var tier in Model.RewardVms) 
    { 
      @Html.Partial("GenerateReward", tier) // in this partial view in the BeginCollectionItem     
    } 



@foreach (var warranties in Model.WarrantyFeaturesVm) 
{ 
    using (Html.BeginCollectionItem("WarrantyFeaturesVm")) 
    { 
     <span>@warranties.Name:</span> 
     @Html.TextBoxFor(x => warranties.FeatureId) 
     @Html.CheckBoxFor(x => warranties.HasFeature) 
    } 
} 

मैं jQuery का उपयोग कर रहा serializeArray का उपयोग करके डेटा प्रस्तुत करने के लिए() की तरह दिखता है। जब यह सर्वर पर जाता है तो यह सभी गतिशील लोगों को सही ढंग से बांधता है और संग्रह में वारंटी को भी बांधता है (संग्रह गणना 1 है)। फिर भी यह वारंटी FeaturesVm के अंदर कुछ भी बाध्य नहीं करता है, सब कुछ डिफ़ॉल्ट के रूप में छोड़ दिया जाता है।

यदि मैं (Html.BeginCollectionItem("WarrantyFeaturesVm")) का उपयोग कर हटा देता हूं तो यह संग्रह को भी बाध्य नहीं करेगा।

कोई भी जानता है कि यह संग्रह में कुछ भी बाध्यकारी क्यों नहीं है?

संपादित

// for loop (works) 
<form method="post" id="" action="" class="ui-formwizard ui-helper-reset ui-widget ui-widget-content ui-corner-all" novalidate="novalidate"> 

<span id="" class="step ui-formwizard-content ui-helper-reset ui-corner-all" style="display: none;"> 

<input type="hidden" value="6aa20677-d367-4e2a-84f0-9fbe00deb191" name="WarrantyFeaturesVm[0].FeatureId" id="WarrantyFeaturesVm_0__FeatureId" data-val-required="The FeatureId field is required." data-val="true" class="ui-wizard-content ui-helper-reset ui-state-default"> <span>Purchase</span> 
<input type="checkbox" value="true" name="WarrantyFeaturesVm[0].HasFeature" id="WarrantyFeaturesVm_0__HasFeature" data-val-required="The HasFeature field is required." data-val="true" class="ui-wizard-content ui-helper-reset ui-state-default"><input type="hidden" value="false" name="WarrantyFeaturesVm[0].HasFeature" class="ui-wizard-content ui-helper-reset ui-state-default"> 

</form> 




//foreach loop beginItemCollection(does not work) 


<form method="post" id="" action="" class="ui-formwizard ui-helper-reset ui-widget ui-widget-content ui-corner-all" novalidate="novalidate"> 

<span id="" class="step ui-formwizard-content ui-helper-reset ui-corner-all" style="display: inline;"> 

<input type="hidden" value="68ba9241-c409-4f4b-96da-cce13b127c1e" autocomplete="off" name="WarrantyFeaturesVm.index" class="ui-wizard-content ui-helper-reset ui-state-default"> 
<input type="hidden" value="6aa20677-d367-4e2a-84f0-9fbe00deb191" name="WarrantyFeaturesVm[68ba9241-c409-4f4b-96da-cce13b127c1e].war.FeatureId" id="WarrantyFeaturesVm_68ba9241-c409-4f4b-96da-cce13b127c1e__war_FeatureId" data-val-required="The FeatureId field is required." data-val="true" class="ui-wizard-content ui-helper-reset ui-state-default">   <span>Purchase</span> 
<input type="checkbox" value="true" name="WarrantyFeaturesVm[68ba9241-c409-4f4b-96da-cce13b127c1e].war.HasFeature" id="WarrantyFeaturesVm_68ba9241-c409-4f4b-96da-cce13b127c1e__war_HasFeature" data-val-required="The HasFeature field is required." data-val="true" class="ui-wizard-content ui-helper-reset ui-state-default"><input type="hidden" value="false" name="WarrantyFeaturesVm[68ba9241-c409-4f4b-96da-cce13b127c1e].war.HasFeature" class="ui-wizard-content ui-helper-reset ui-state-default"> 

</span> 

</form> 





//for loop beginItemCollection (does not work) 
<form method="post" id="" action="" class="ui-formwizard ui-helper-reset ui-widget ui-widget-content ui-corner-all" novalidate="novalidate"> 


<span id="" class="step ui-formwizard-content ui-helper-reset ui-corner-all" style="display: none;"> 

<input type="hidden" value="fe3fbc82-a2df-476d-a15a-dacd841df97e" autocomplete="off" name="WarrantyFeaturesVm.index" class="ui-wizard-content ui-helper-reset ui-state-default"> 
<input type="hidden" value="6aa20677-d367-4e2a-84f0-9fbe00deb191" name="WarrantyFeaturesVm[fe3fbc82-a2df-476d-a15a-dacd841df97e].WarrantyFeaturesVm[0].FeatureId" id="WarrantyFeaturesVm_fe3fbc82-a2df-476d-a15a-dacd841df97e__WarrantyFeaturesVm_0__FeatureId" data-val-required="The FeatureId field is required." data-val="true" class="ui-wizard-content ui-helper-reset ui-state-default">   <span>Purchase</span> 
<input type="checkbox" value="true" name="WarrantyFeaturesVm[fe3fbc82-a2df-476d-a15a-dacd841df97e].WarrantyFeaturesVm[0].HasFeature" id="WarrantyFeaturesVm_fe3fbc82-a2df-476d-a15a-dacd841df97e__WarrantyFeaturesVm_0__HasFeature" data-val-required="The HasFeature field is required." data-val="true" class="ui-wizard-content ui-helper-reset ui-state-default"><input type="hidden" value="false" name="WarrantyFeaturesVm[fe3fbc82-a2df-476d-a15a-dacd841df97e].WarrantyFeaturesVm[0].HasFeature" class="ui-wizard-content ui-helper-reset ui-state-default"> 

</span> 

<span id="adminSettings" class="step ui-formwizard-content ui-helper-reset ui-corner-all" style="display: inline;"> 

</form> 
+0

और आपकी फ़ोरैच वारंटी एचटीएमएल के अंदर है। बेगिनफॉर्म? क्या आप वॉरंटी के सेट के लिए कुछ नमूना HTML आउटपुट पोस्ट करना चाहते हैं? – danludwig

+0

हां वे एक HTML.BeginForm में हैं। मुझे लगता है कि मैंने इसे समझ लिया (आंशिक रूप से)। अगर मैं फोरच लूप को फ़ोरलोप में बदलता हूं तो कुछ @ html.TextBoxFor (x => Model.WarrantyFeaturesVm [i]। FatureatureId) जैसे कुछ करता है। निश्चित नहीं है कि क्यों प्रारंभिक चयन काम नहीं कर रहा है। – chobo2

+0

मॉडल बाइंडर एचटीएमएल को देखता है। 2 अलग-अलग मामलों में HTML आईडी को अलग-अलग कैसे प्रस्तुत किया जाता है, इस अंतर को देखें। हम BeginCollectionItem के साथ अक्सर foreach का उपयोग करते हैं, लेकिन अक्सर BeginCollectionItem आंशिक या संपादक टेम्पलेट में है। – danludwig

उत्तर

8

ठीक है मुझे लगता है कि मैं देख रहा हूँ यहाँ क्या चल रहा है।

दूसरा नमूना है, जहां आप foreach, ऐसा लगता है कि आपकी cshtml की तरह कुछ इस तरह (@ प्रतीकों गलत हो सकता है) था:

foreach (var war in Model.WarrantyFeaturesVm) { 
    using (Html.BeginCollectionItem("WarrantyFeaturesVm")) { 
     Html.HiddenFor(m => war.FeatureId) 
     <span>@Html.DisplayFor(m => war.Name)</span> 
     Html.HiddenFor(m => war.HasFeature) 
    } 
} 

क्योंकि BeginCollectionItem एचटीएमएल नाम प्राप्त करने के लिए उसके संदर्भ का उपयोग करता है और आईडी है, यही कारण है कि आप आईडी और नामों में "युद्ध" के साथ समाप्त होते हैं। मॉडल बाइंडर "वारंटी FeaturesVm" नामक एक संग्रह संपत्ति की तलाश में है, जो इसे पाता है। हालांकि यह वारंटी FeaturesVm viewmodel पर "युद्ध" नाम की एक संपत्ति की तलाश में है, जिसे वह नहीं मिल सकता है, और इस प्रकार बाध्य नहीं होता है।

<input type="hidden" value="6aa20677-d367-4e2a-84f0-9fbe00deb191" 
    name="WarrantyFeaturesVm[68ba9241-c409-4f4b-96da-cce13b127c1e].war.FeatureId" 
    id="WarrantyFeaturesVm_68ba9241-c409-4f4b-96da-cce13b127c1e__war_FeatureId" .../> 

तीसरे परिदृश्य में, यह समान है। यह WarranyFeaturesVm संग्रह संपत्ति की तलाश में है, जो इसे पाता है। हालांकि यह एक और संग्रह आइटम की तलाश में है।

<input type="hidden" value="6aa20677-d367-4e2a-84f0-9fbe00deb191" 
    name="WarrantyFeaturesVm[fe3fbc82-a2df-476d-a15a-dacd841df97e].WarrantyFeaturesVm[0].FeatureId" 
    id="WarrantyFeaturesVm_fe3fbc82-a2df-476d-a15a-dacd841df97e__WarrantyFeaturesVm_0__FeatureId" .../> 

आदेश सही ढंग से बाध्य करने में, अपने HTML अपना पहला एचटीएमएल उदाहरण की तरह देखने के लिए है:

<input type="hidden" value="68ba9241-c409-4f4b-96da-cce13b127c1e" 
    name="WarrantyFeaturesVm.index" .../> 
<input type="hidden" value="6aa20677-d367-4e2a-84f0-9fbe00deb191" 
    name="WarrantyFeaturesVm[68ba9241-c409-4f4b-96da-cce13b127c1e].FeatureId" 
    id="WarrantyFeaturesVm_68ba9241-c409-4f4b-96da-cce13b127c1e__FeatureId" .../> 

की तरह मैं अपने टिप्पणी में संकेत दिया है, तो आप BeginCollectionItem और यह सब कुछ डाल कर इस लक्ष्य को हासिल कर सकते हैं आंशिक दृश्य में लपेटता है। आंशिक दृश्य तो, अपने स्वयं के संदर्भ प्राप्त होगा के बाद से अपने सहायकों तो जैसे पुरज़ोर टाइप सहायकों के साथ दृश्य के @Model संपत्ति का उपयोग करेगा: यदि आप वास्तव में संग्रह की जरूरत है प्रदान करने, @Html.WidgetFor(m => m.PropertyName).

दूसरी ओर बाहरी दृश्य, मुझे लूप के साथ और BeginCollectionItem के बिना सामान्य अनुक्रमण (पूर्णांक-आधारित) का उपयोग करके कोई समस्या नहीं दिखाई देती है।

अद्यतन

मैं this old post from Phil Haack अप खोदा। एक अंश:

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

<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> 

BeginCollectionItem यकीन है कि मॉडल बंधन होता है बनाने के लिए इस अनुक्रमण विधि का उपयोग करता है। एकमात्र अंतर यह है कि यह इंडेक्स के रूप में इंट्स के बजाय Guids का उपयोग करता है। लेकिन आप उपरोक्त फिल के उदाहरण में मैन्युअल रूप से किसी भी इंडेक्सर को सेट कर सकते हैं।

+0

आह। मुझे यह कोशिश करनी होगी। हां मैं सिर्फ पूर्णांक आधारित तरीके का उपयोग करने जा रहा हूं लेकिन मैंने पहले सोचा था कि किसी भी तरह सहायक सहायक प्रभाव दे रहा था कि वास्तव में जब मैं इसे गलत कर रहा था। – chobo2

+0

BeginCollectionItem सही नहीं है। यह एकमात्र चीज है जिसे मैं 10 साल पहले PHP करने के बारे में याद करता हूं। अगर मैं एमवीसी आपको इनपुट आईडी = "कलेक्शनप्रोपर्टी []" का उपयोग करके संग्रह में पास करने देता हूं तो मुझे यह अच्छा लगेगा। इतना आसान होगा। – danludwig

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