asp.net mvc tutorial EditorDemplate में DropDownListFor मूल्य का चयन नहीं कर रहा है




mvc tutorial (10)

मेरे पास एक कस्टम ऑब्जेक्ट के लिए एक संपादक टेम्पलेट है। उस संपादक टेम्पलेट के अंदर मैं कुछ DropDownListFor मददगार का उपयोग करता हूं। उनमें से प्रत्येक में मैं एक अद्वितीय मॉडल प्रॉपर्टी (पूर्व-चयनित मान के साथ) और सभी चयन विकल्पों वाली चुनिंदा सूची निर्दिष्ट करता हूं।

उदाहरण:

<%=Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %>

मुझे पता है कि विकल्प मान पॉप्युलेट किए जा रहे हैं (स्रोत देखने से) और मेरा मॉडल सही आईडी मान (DocumentCategoryType) के साथ पास हो गया है।

जब दृश्य प्रस्तुत किया जाता है, तो मेरे ड्रॉपडाउन में कोई चयनित आइटम नहीं होता है और इसलिए यह पहले (गैर-चयनित) मान पर डिफ़ॉल्ट होता है।

क्या किसी के पास कोई विचार है?

धन्यवाद।


एएसपी.नेट एमवीसी 2 स्रोत कोड के माध्यम से देखकर इस समस्या के कुछ समाधान सामने आते हैं। अनिवार्य रूप से, SelectListItem में किसी भी SelectListItem सहायक विस्तार विधि में पारित किया गया है जिसमें Selected संपत्ति सेट सही है, आइटम के लिए लागू selected विशेषता के साथ प्रदान किए गए <option> तत्व पर कोई असर नहीं है।

<option> तत्वों पर selected विशेषता द्वारा निर्धारित किया जाता है

1) जांच कर रहा है कि सहायक विस्तार विधि को एक SelectList पास कर SelectList । यदि यह शून्य है, तो फ्रेमवर्क व्यूडेटा को उस कुंजी के अनुरूप मान के लिए देखेगा जो दृश्य मॉडल प्रॉपर्टी है जिसके लिए आप ड्रॉप डाउन सूची प्रस्तुत करना चाहते हैं। यदि मान एक SelectList , तो इसका उपयोग <select> को किसी भी चयनित मान को शामिल करने के लिए किया जाएगा, जब तक कि मॉडल प्रॉपर्टी के लिए मॉडल स्थिति शून्य न हो।

2) यदि एक SelectList सूची सहायक सूची विधि में पारित की गई है और मॉडल प्रॉपर्टी के लिए मॉडल स्थिति शून्य है, तो मॉडल प्रॉपर्टी नाम कुंजी के रूप में फ्रेमवर्क डिफ़ॉल्ट मान के लिए व्यूडेटा में दिखेगा। व्यू डेटा में मूल्य को स्ट्रिंग में परिवर्तित किया जाता है और SelectList में किसी भी आइटम को हेल्पर एक्सटेंशन विधि में पास किया जाता है जिसमें मूल्य होता है (यदि कोई मान सेट नहीं है, तो टेक्स्ट चेक किया जाएगा) जो डिफ़ॉल्ट मान से मेल खाता है Selected संपत्ति होगी सत्य पर सेट करें जो बदले में <option> selected="selected" विशेषता selected="selected" साथ प्रस्तुत करेगा।

इसे एक साथ रखकर, दो व्यावहारिक विकल्प हैं जिन्हें मैं एक विकल्प चुनने के लिए देख सकता हूं और दृढ़ता से टाइप किए गए DropDownListFor उपयोग कर सकता हूं:

निम्नलिखित दृश्य मॉडल का उपयोग करना

public class CategoriesViewModel
{
    public string SelectedCategory { get; private set ; }
    public ICollection<string> Categories { get; private set; }

    public CategoriesViewModel(string selectedCategory, ICollection<string> categories)
    {
        SelectedCategory = selectedCategory;
        Categories = categories;
    }
}

विकल्प 1

ड्रॉपडाउन प्रस्तुत करने के लिए उपयोग किए गए संग्रह के संपत्ति नाम के विरुद्ध आपके दृश्य को रेंडर करने वाले नियंत्रक में व्यूडेटा में एक मान सेट करें

नियंत्रक कार्रवाई

public class CategoriesController
{
    [HttpGet]
    public ViewResult Select()
    {
        /* some code that gets data from a datasource to populate the view model  */
        ICollection<string> categories = repository.getCategoriesForUser();
        string selectedCategory = repository.getUsersSelectedCategory();

        CategoriesViewModel model = new CategoriesViewModel(selectedCategory, categories);
        this.ViewData["Categories"] = selectedCategory;        

        return View(model);
    }

    [HttpPost]
    public ActionResult Select(CategoriesViewModel model)
    {
        /* some code that does something */
    }
}

और दृढ़ता से टाइप किए गए दृश्य में

<%: Html.DropDownListFor(m => m.Categories, Model.Categories.Select(c => new SelectListItem { Text = c, Value = c }), new { @class = "my-css-class" }) %>

विकल्प 2

चयनित आइटम की संपत्ति के नाम का उपयोग करके ड्रॉपडाउन प्रस्तुत करें

नियंत्रक कार्रवाई

public class CategoriesController
{
    [HttpGet]
    public ViewResult Select()
    {
        /* some code that gets data from a datasource to populate the view model  */
        ICollection<string> categories = repository.getCategoriesForUser();
        string selectedCategory = repository.getUsersSelectedCategory();

        CategoriesViewModel model = new CategoriesViewModel(selectedCategory, categories);

        return View(model);
    }

    [HttpPost]
    public ActionResult Select(CategoriesViewModel model)
    {
        /* some code that does something */
    }
}

और दृढ़ता से टाइप किए गए दृश्य में

<%: Html.DropDownListFor(m => m.SelectedCategory, Model.Categories.Select(c => new SelectListItem { Text = c, Value = c }), new { @class = "my-css-class" }) %>

यहां एक और अच्छा समाधान है यदि आपकी ड्रॉप डाउन सूची का स्रोत एक चयन सूची के बजाय एक आईनेमरेबल है:

public static SelectList MakeSelection(this IEnumerable<SelectListItem> list, object selection, string dataValueField = "Value", string dataTextField = "Text")
{
    return new SelectList(list, dataValueField, dataTextField, selection);
}


मैं अपने चयनसूची की इतनी सारी प्रतियां बनाने के प्रदर्शन के बारे में चिंतित था, इसलिए इसके बजाय, मैंने चयनित गुण को कस्टम विशेषता के रूप में जोड़ा, फिर वास्तव में आइटम का चयन करने के लिए jquery का उपयोग किया गया:

@Html.DropDownListFor(item => item.AttendeeID, attendeeChoices, String.Empty, new { setselectedvalue = Model.AttendeeID })

........


jQuery("select[setselectedvalue]").each(function () { e = jQuery(this); e.val(e.attr("setselectedvalue")); });

मैं फॉलोिंग कहकर एक ही समस्या को हल करने में कामयाब रहा:

new SelectList(sections.Select(s => new { Text = s.SectionName, Value = s.SectionID.ToString() }), "Value", "Text")

यह चाल मान को एक स्ट्रिंग में परिवर्तित कर रही है। मुझे पता है कि पिछले उत्तरों में इसका उल्लेख किया गया है लेकिन मुझे मेरा समाधान थोड़ा क्लीनर मिल गया है :)। उम्मीद है की यह मदद करेगा।


मुझे इस क्षेत्र में प्रोग्राम नाम के साथ भी समस्या थी। बाहर निकलता है हमने बेसकंट्रोलर और लेआउट.cshtml में ViewBag.ProgramName का उपयोग किया, और यह एक अलग उद्देश्य के लिए था। चूंकि ViewBag.ProgramName में मान ड्रॉपडाउन सूची में नहीं मिला था, तब भी कोई मान नहीं चुना गया था, भले ही SelectListItem.Selected सूची में एक आइटम के लिए सही था। हमने व्यूबैग को एक अलग कुंजी का उपयोग करने के लिए बदल दिया और समस्या हल हो गई।


यह एक बग @ aspnet.codeplex.com के रूप में पुष्टि की जाती है और दृढ़ता से टाइप किए गए विचारों के लिए केवल इस तरह व्यवहार करती है।

वर्कअराउंड: व्यू कोड में अपनी सिलेक्टलिस्ट को पॉप्युलेट करें

पसंद

<%= Html.DropDown("DocumentCategoryType", new SelectList(Model.Categories,"id","Name",Model.SelectedCategory")) =>

हमने एक नई SelectList को SelectList करके समाधान भी हल किया है जिसमें उपयुक्त SelectListItem चुना गया है, लेकिन SelectListItem को कॉल को थोड़ा क्लीनर के लिए कॉल रखने के लिए इस एक्सटेंशन विधि को बनाया गया है:

public static SelectList MakeSelection(this SelectList list, object selection)
{
    return new SelectList(list.Items, list.DataValueField, list.DataTextField, selection);
}

फिर आपकी DropDownListFor कॉल बन जाती है:

<%= Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList.MakeSelection(Model.DocumentCategoryType)) %>

सुनिश्चित करें कि जब आप इसे दृश्य में भेजते हैं तो आपके पास m.DocumentCategoryType को असाइन किया गया मान होता है।

आम तौर पर जब आप एक पोस्ट वापस करते हैं तो यह मान रीसेट हो जाएगा, इसलिए आपको अपने दृश्य पर लौटने पर केवल मूल्य निर्दिष्ट करने की आवश्यकता है।

ड्रॉप डाउन सूची बनाते समय आपको इसे दो मानों को पारित करने की आवश्यकता होती है। 1. यह वह जगह है जहां आप चयनित मूल्य 2 स्टोर करेंगे। वास्तविक सूची है

उदाहरण

<%=Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %>

मैंने चयनित सूची आइटम को सही मान को सही मान सेट करने की गलती की है। यह कुछ भी नहीं करेगा। इसके बजाय बस अपने नियंत्रक में m.DocumentCategoryType के लिए एक मान असाइन करें और यह वास्तव में आपके लिए चयन करेगा।


मेरी परियोजना से चिपकाया गया कॉपी किया गया:

<%= Html.DropDownListFor(m => m.Profession.Profession_id, new SelectList(Model.Professions, "Profession_id", "Profession_title"),"-- Profession --")%>

मॉडल पारित किया गया है:

   ...
            public Profession Profession { get; set; }
            public IList<Profession> Professions { get; set; }
    ...

एचटीएमएल उत्पन्न:

  <select id="Profession_Profession_id" name="Profession.Profession_id">
    <option value="">-- Profesion --</option>
    <option value="4">Informatico</option>
    <option selected="selected" value="5">Administracion</option>
    </select> 

मेरे लिये कार्य करता है। मेरे पास यह फॉर्म है और एकमात्र नुकसान यह है कि यदि मॉडल वैध नहीं है और मैं मॉडल को वापस देखने के लिए वापस लौटाता हूं तो मुझे व्यवसायों की सूची को फिर से लोड करना होगा।

obj.Professions = ProfileService.GetProfessions();
return View(obj);






asp.net-mvc