2012-07-26 14 views
18

क्षमा करें यदि इससे पहले पूछा गया है; वाक्यांश के दस लाख तरीके हैं, इसलिए एक उत्तर खोजना मुश्किल साबित हुआ है।एमवीसी 3 - जटिल प्रकारों की सूची के साथ व्यूमोडेल

public class SelectableDeviceViewModel 
{ 
    public int DeviceInstanceId { get; set; } 
    public bool IsSelected { get; set; } 
    public string Name { get; set; } 
} 

मेरे विचार में, मैं संपादन योग्य चेक बॉक्स की एक सूची प्रदर्शित करने का प्रयास कर रहा हूँ:

public class AssignSoftwareLicenseViewModel 
{ 
    public int LicenseId { get; set; } 
    public ICollection<SelectableDeviceViewModel> Devices { get; set; } 
} 

SelectableDeviceViewModel का एक सरलीकृत संस्करण इस होगा:

मैं निम्नलिखित गुणों के साथ एक viewmodel है एक इनपुट फॉर्म के अंदर, डिवाइस संपत्ति के लिए। वर्तमान में, मेरे विचार इस तरह दिखता है:

@using (Html.BeginForm()) 
{ 
    @Html.HiddenFor(x => Model.LicenseId) 
    <table> 
     <tr> 
      <th>Name</th> 
      <th></th> 
     </tr> 
     @foreach (SelectableDeviceViewModel device in Model.Devices) 
     { 
      @Html.HiddenFor(x => device.DeviceInstanceId) 
      <tr> 
       <td>@Html.CheckBoxFor(x => device.IsSelected)</td> 
       <td>@device.Name</td> 
      </tr> 
     } 
    </table> 

    <input type="submit" value="Assign" /> 
} 

समस्या है, जब मॉडल वापस नियंत्रक पर पोस्ट हो जाती, उपकरण रिक्त है।

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

कोई विचार क्या मैं यहां गलत कर रहा हूं?

+0

क्या आप हमें अपना नियंत्रक कोड दिखा सकते हैं जो डेटा मॉडल को पॉप्युलेट कर रहा है? इस क्षेत्र को कवर करने वाले सबसे सुंदर वर्णन प्रश्न के लिए – nikeaa

+2

+1। मेरा विश्वास करो, हमने पिछले 2 घंटों को इस समस्या के लिए चारों ओर देखकर बिताया है! –

उत्तर

30

मेरे धारणा यह हो रहा है कि क्योंकि भले ही मैं इसकी सामग्री का संपादन, उपकरण संपत्ति के रूप में शामिल किए गए कभी नहीं स्पष्ट रूप से है।

नहीं, आपकी धारणा गलत है। कारण यह ठीक से बाध्य नहीं होता है क्योंकि आपके इनपुट फ़ील्ड में सही नाम नहीं हैं। उदाहरण के लिए उन्हें name="Devices[0].IsSelected" के बजाय name="IsSelected" कहा जाता है। सही तार प्रारूप पर एक नज़र डालें जिसे संग्रह से बांधने के लिए उपयोग करने की आवश्यकता है: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

लेकिन ऐसा क्यों होता है?

यह foreach लूप के कारण होता है जिसे आपने अपने विचार में उपयोग किया था। आपने x => device.IsSelected को चेकबॉक्स के लिए लैम्ब्डा अभिव्यक्ति के रूप में उपयोग किया था, लेकिन यह डिवाइस की संपत्ति को ध्यान में रखता नहीं है (जैसा कि आप अपने वेब पेज के जेनरेट किए गए स्रोत कोड को देखकर देख सकते हैं)।

तो मुझे क्या करना चाहिए?

व्यक्तिगत रूप से मैं आपको संपादक टेम्पलेट्स का उपयोग करने की सलाह दूंगा क्योंकि वे जटिल गुणों के नेविगेशन संदर्भ का सम्मान करते हैं और सही इनपुट नाम उत्पन्न करते हैं। तो अपने ध्यान में रखते हुए पूरे foreach पाश से छुटकारा पाने और कोड की एक पंक्ति के साथ बदलना:

@Html.EditorFor(x => x.Devices) 

और अब कि स्वचालित रूप से के प्रत्येक तत्व के लिए ASP.NET MVC द्वारा प्रदान की गई हो जाएगा एक कस्टम संपादक टेम्पलेट को परिभाषित उपकरण संग्रह।चेतावनी: ~/Views/Shared/EditorTemplates/SelectableDeviceViewModel.cshtml:

@model SelectableDeviceViewModel 
@Html.HiddenFor(x => x.DeviceInstanceId) 
<tr> 
    <td>@Html.CheckBoxFor(x => x.IsSelected)</td> 
    <td>@Html.DisplayFor(x => x.Name)</td> 
</tr> 

एक और दृष्टिकोण (जो मैं अनुशंसा नहीं करते) आपके विचार मॉडल में अपने वर्तमान ICollection बदलने के लिए है स्थान और इस टेम्पलेट का नाम इस रूप में बहुत महत्वपूर्ण हैं प्रथा के अनुसार काम करता है एक अनुक्रमित संग्रह करने के लिए (जैसे कि एक IList<T> या किसी सरणी T[] के रूप में):

public class AssignSoftwareLicenseViewModel 
{ 
    public int LicenseId { get; set; } 
    public IList<SelectableDeviceViewModel> Devices { get; set; } 
} 

और फिर बजाय foreach के for पाश का उपयोग :

@for (var i = 0; i < Model.Devices.Count; i++) 
{ 
    @Html.HiddenFor(x => x.Devices[i].DeviceInstanceId) 
    <tr> 
     <td>@Html.CheckBoxFor(x => x.Devices[i].IsSelected)</td> 
     <td>@Html.DisplayFor(x => x.Devices[i].Name</td> 
    </tr> 
} 
+1

संपादक टेम्पलेट पूरी तरह से काम करता है; आपका बहुत बहुत धन्यवाद! – InsqThew

+1

ग्रेट उत्तर लेकिन आप दृश्य मॉडल में अनुक्रमित संग्रह का उपयोग करने की सलाह क्यों नहीं देते? –

+1

@JamieIde, क्योंकि मैं संपादक टेम्पलेट का उपयोग करना पसंद करता हूं। विचारों में लूप क्यों लिखते हैं जब यह ढांचे के द्वारा आपके लिए पहले से ही लिया जाता है? –

0

संपादक के लिए टेम्पलेट काम करते हैं और कोड को साफ रखते हैं। आपको लूप की आवश्यकता नहीं है और मॉडल को सही ढंग से पोस्ट किया गया है।

हालांकि, क्या किसी को जटिल दृश्य मॉडल (नेस्टेड संपादक के लिए टेम्पलेट्स) पर सत्यापन के साथ समस्याएं हैं? मैं केंडो वैलिडेटर का उपयोग कर रहा हूं और सभी प्रकार की jquery त्रुटियों में चल रहा हूं।

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