2011-08-28 7 views
5

का उपयोग कर एमवीसी 3/रेजर में ड्रॉपडाउनलिस्ट को सॉर्ट करने का सबसे अच्छा तरीका हाय, इसलिए मैं एमवीसी 3 और रेजर के लिए काफी नया हूं और मैं पिछले कुछ दिनों में अपने सिर को पाने की कोशिश कर रहा हूं। मुझे अपने प्रोजेक्ट आर्किटेक्ट द्वारा एक सहायक विधि बनाने के लिए एक कार्य दिया गया है जो एक एमवीसी व्यू में एक ड्रॉप डाउन सूची टाइप करता है। मेरे पास एक ऐसा दृश्य है जो नियंत्रक से विभिन्न डेटा पुनर्प्राप्त करता है और मैं कुछ मान वापस कर रहा हूं जिन्हें मैं ड्रॉप डाउन सूची में दिखाना चाहता हूं। मुझे बताया गया है कि इसे नियंत्रक में सॉर्ट न करें और उस क्षेत्र को पारित करने के लिए जिसे हम सहायक विधि में सॉर्ट करना चाहते हैं। मैं इसे नीचे की तरह कर सकता है लेकिन वास्तुकार ग तेज कोड से मुक्त दृश्य रखना चाहता है:हेल्पर विधि

@Html.DropDownListFor(model => model.StudyName, new SelectList(ViewBag.StudyTypes, "Value", "Text").OrderBy(l => l.Text)) 

तो मैं कुछ नमूना कोड और कुछ विस्तार तरीकों कोशिश करते हैं और यह काम करने के लिए प्राप्त करने के लिए बनाया है। मेरा विचार मौजूदा Html.DropDownList विधि को दोहराना है और 'ऑब्जेक्ट htmlAttributes' को पारित करने की अनुमति देना है ताकि मैं शैली कॉल के हिस्से के रूप में शैली सेट कर सकूं।

यहां मेरा कोड अभी तक है। मैं संपादित नियंत्रक विधि में ViewBag.StudyTypes में गिरावट के लिए डेटा लौटने कर रहा हूँ नीचे:

public ActionResult Edit(int id) 
{ 
    IEnumerable<SelectListItem> mySelectList = new List<SelectListItem>(); 
    IList<SelectListItem> myList = new List<SelectListItem>(); 

    for (int i = 0; i < 5; i++) 
    { 
     myList.Add(new SelectListItem() 
      { Value = i.ToString(), Text = "My Item " + i.ToString(), Selected = i == 2 } 
     ); 
    } 

    mySelectList = myList; 
    ViewBag.StudyTypes = mySelectList; 

    StudyDefinition studydefinition = db.StudyDefinitions.Find(id); 

    return View(studydefinition); 
} 

यहाँ मेरी देखें कोड है:

@model MyStudyWeb.Models.StudyDefinition 

@using MyStudyWeb.Helpers 

@{ 
    ViewBag.Mode = "Edit"; 
} 
<div> 
    @Html.DropDownListSorted(new SelectList(ViewBag.StudyTypes, "Value", "Text"))<br /> 
    @Html.DropDownListSorted("MyList", new SelectList(ViewBag.StudyTypes, "Value", "Text"))<br /> 
</div> 

अंत में नीचे विस्तार तरीकों मैं कोशिश कर रहा हूँ कर रहे हैं काम करने के लिए मिलता है। पहली विस्तार विधि कुछ भी नहीं करती है, मुझे दृश्य में उस बिंदु पर बस एक रिक्त स्थान मिलता है। दूसरी विधि काम करता है लेकिन यह बदसूरत है। तीसरी विधि के लिए मुझे नहीं पता कि 'ऑर्डर बाय' पैरामीटर को कैसे निर्दिष्ट किया जाए क्योंकि ऑयनेबरेबल पर ऑर्डरबी एक लिंक अभिव्यक्ति की अपेक्षा करता है।

namespace StudyDefinition.Helpers 
{ 
    public static class HtmlHelperExtensions 
    { 
     // 1st sort method: sort the passed in list and return a new sorted list 
     public static SelectList DropDownListSorted(this HtmlHelper helper, IEnumerable<SelectListItem> selectList) 
     { 
      var x = new SelectList(selectList.ToList()).OrderBy(l => l.Text); 

      return x as SelectList; 
     } 

     // 2nd sort method: return IHtml string and create <select> list manually 
     public static IHtmlString DropDownListSorted(this HtmlHelper helper, string name, SelectList selectList) 
     { 
      StringBuilder output = new StringBuilder(); 
      (selectList).OrderBy(l => l.Text); 

      output.Append("<select id=" + name + " name=" + name + ">"); 

      foreach (var item in selectList) 
      { 
       output.Append("<option value=" + item.Value.ToString() + ">" + item.Text + "</option>"); 
      } 

      output.Append("</select>"); 

      return MvcHtmlString.Create(output.ToString()); 
     } 

     // 3rd sort method: pass in order by parameter - how do I use this? 
     public static IHtmlString DropDownListSorted(this HtmlHelper helper, string name, SelectList selectList, string orderBy) 
     { 
      StringBuilder output = new StringBuilder(); 

      //How do I use the orderBy parameter? 
      (selectList).OrderBy(l => l.Text); 

      output.Append("<select id=" + name + " name=" + name + ">"); 

      foreach (var item in selectList) 
      { 
       output.Append("<option value=" + item.Value.ToString() + ">" + item.Text + "</option>"); 
      } 

      output.Append("</select>"); 

      return MvcHtmlString.Create(output.ToString()); 
     }   
    } 
} 

मैं वास्तव में सबसे अच्छा तरीका लेने के लिए पता नहीं है, वहाँ एक बहुत सरल तरीका है कि मैं पूरी तरह याद कर रहा हूँ हो सकता है और मैं बिंदु पर हो सकता है, जहां मैं पेड़ों के लिए लकड़ी नहीं देख सकते हैं अब और। कुछ प्रश्न

  • क्या मुझे एक चयनसूची या एक एमवीसीएचटीएमएलस्ट्रिंग, या पूरी तरह से कुछ और वापस करना चाहिए?

  • पहली विस्तार विधि के लिए मैं दृश्य में प्रस्तुत करने के लिए लौटाई गई चयनसूची कैसे प्राप्त करूं?

  • सॉर्ट ऑर्डर निर्दिष्ट करने वाले मेरे एक्सटेंशन विधियों के पैरामीटर में कैसे पास किया जाए?

  • मैं 'ऑब्जेक्ट htmlAttributes' पैरामीटर कैसे पास करूं, और मैं इस ऑब्जेक्ट/पैरामीटर को SelectList पर कैसे लागू करूं?

किसी को भी कुछ विचार या सुझाव है तो मैं कुछ प्रतिक्रिया :)

उत्तर

5

पहली और अपने कोड का सबसे महत्वपूर्ण हिस्सा कि सराहना करेंगे किसी भी ViewBag/ViewData से छुटकारा पाने के लिए होगा (जो मैं व्यक्तिगत रूप से एमवीसी अनुप्रयोगों के लिए कैंसर के रूप में विचार करें) और दृश्य मॉडल और दृढ़ता से टाइप किए गए विचारों का उपयोग करें।

तो चलो एक दृश्य के मॉडल है जो डेटा हमारे विचार (इस उदाहरण में एक dropdownlistg) के साथ काम किया जाएगा प्रतिनिधित्व करेंगे को परिभाषित करते हुए प्रारंभ करते हैं:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     var model = new MyViewModel 
     { 
      // I am explicitly putting some items out of order 
      Items = new[] 
      { 
       new SelectListItem { Value = "5", Text = "Item 5" }, 
       new SelectListItem { Value = "1", Text = "Item 1" }, 
       new SelectListItem { Value = "3", Text = "Item 3" }, 
       new SelectListItem { Value = "4", Text = "Item 4" }, 
      } 
     }; 
     return View(model); 
    } 
} 
:

public class MyViewModel 
{ 
    public string SelectedItem { get; set; } 
    public IEnumerable<SelectListItem> Items { get; set; } 
} 

तो हम एक नियंत्रक हो सकता था

और एक दृश्य:

@model MyViewModel 
@Html.DropDownListForSorted(
    x => x.SelectedItem, 
    Model.Items, 
    new { @class = "foo" } 
) 

और अंत में पिछले टुकड़ा सहायक पूरा किया जाता है विभागाध्यक्ष जो मूल्य से लटकती सॉर्ट जाएगा (आप इसे पाठ के आधार पर सॉर्ट खुद को अनुकूलित कर):

public static class HtmlExtensions 
{ 
    public static IHtmlString DropDownListForSorted<TModel, TProperty>(
     this HtmlHelper<TModel> helper, 
     Expression<Func<TModel, TProperty>> expression, 
     IEnumerable<SelectListItem> items, 
     object htmlAttributes 
    ) 
    { 
     var model = helper.ViewData.Model; 
     var orderedItems = items.OrderBy(x => x.Value); 
     return helper.DropDownListFor(
      expression, 
      new SelectList(orderedItems, "Value", "Text"), 
      htmlAttributes 
     ); 
    } 
} 
+0

हाय @ डारिन यह बहुत अच्छा धन्यवाद है। हालांकि, कुछ मुद्दों पर, मैं मौजूदा सिस्टम पर काम कर रहा हूं और सभी विचारों में कई ड्रॉप डाउन सूचियां हैं, और वे सभी अपने नियंत्रकों से व्यूबैग गुणों के रूप में लौट आए हैं। तो मैं वास्तव में इस दृष्टिकोण को बदल नहीं सकता। दूसरा, दृश्य पहले से ही 'रिटर्न व्यू (अध्ययन परिभाषा)' कर रहा है जो इकाई वर्ग है। क्या कोई और तरीका है कि मैं एक दृश्य मॉडल वापस कर सकता हूं? तीसरा जब मैं आपकी विस्तार विधि जोड़ता हूं तो DropDownListFor विधि को पहचाना नहीं जाता है, मुझे मिल रहा है: 'System.Web.Mvc.HtmlHelper' में 'DropDownListFor' –

+3

@Ciaran Bruen, मौजूदा सिस्टम और व्यूबैग के लिए ठीक नहीं है । इस बुरे अभ्यास से बचने के लिए मैंने अभी भविष्य के कोड के लिए इसका उल्लेख किया है। यदि आपके पास एकाधिक ड्रॉपडाउनलिस्ट हैं, तो आपके पास अपने दृश्य मॉडल पर एकाधिक 'IENumerable 'गुण होंगे। 'रिटर्न व्यू (अध्ययन परिभाषा) 'के बारे में, दृश्य दृश्यों को देखने के लिए यह सही तरीका है। तीसरा, 'DropDownListFor' एक्सटेंशन विधि को 'System.Web.Mvc.Html' नेमस्पेस में परिभाषित किया गया है, इसलिए इसे' ड्रॉपडाउनलिस्ट फॉरफोर्डेड 'हेल्पर युक्त फ़ाइल के शीर्ष पर इस नामस्थान में आसानी से उपयोग करने के लिए इसे एक दायरे में लाने के लिए जोड़ें । –

0

आप एक डेटाबेस का उपयोग कर रहे हैं, तो आप

using (BDMMContext dataContext = new BDMMContext()) 
{ 
foreach (Arquiteto arq in dataContext.Arquitetos.SqlQuery("SELECT * FROM Arquitetos ORDER BY Nome")) 
        { 
         SelectListItem selectItem = new SelectListItem { Text = arq.Nome, Value = arq.Arquiteto_Id.ToString() }; 
         // 
         list.Add(selectItem); 
        } 
} 
0

बस प्रकार तत्व को निर्धारित करने के लिए एक क्वेरी का उपयोग कर सकते हैं आइटम को ड्रॉपडाउन सूची में वापस करने से पहले सॉर्टिंग में जोड़ें।

यह करें:

मॉडल: StudyViewModel.cs

public class StudyViewModel { 
    public string StudyName { get; set; } 
    public string StudyTypes { get; set; } 
} 

नियंत्रक: StudyController.cs

using System.Web.Mvc; 
public class StudyController 
{ 
    public List<SelectListItem> studyTypes() 
    { 
     List<SelectListItem> itemList = new List<SelectListItem>(); 
     for (var i=0; i<5; i++) 
     { 
      itemList.Add = new SelectListItem({ 
       Value = i.ToString(); 
       Text = "My Item"; 
      }); 
     } 
     // You can sort here.... 
     List<SelectListItem> sortedList = itemList.OrderBy(x=>x.Text); 
     return sortedList; 
    } 

    public ActionResult Edit(int id) 
    { 
     //You won't need this because you get it using your 
     //controller's routine, instead 
     //ViewBag.StudyTypes = studySlots.OrderBy(e => e.Value); 

     //-- unless you need to add these values to the model for 
     // some reason (outside of filling the ddl), in which case.... 
     // StudyViewModel svm = new StudyViewModel(); 
     // svm.StudyTypes = studySlots.OrderBy(e => e.Value); 
     // svm.StudyName = "My Item"; 
     // return View(svm); 

     // Otherwise, just.... 
     return View(); 
    } 
} 

दृश्य: Edit.cshtml

@Html.DropDownListFor(model => model.StudyName) 
    .OptionLabel('Select...') 
    .DataTextField('Text') 
    .DataValueField('Value') 
    .Datasource(source => 
    { 
     // This is where you populate your data from the controller 
     source.Read(read => 
     { 
      read.Action("studyTypes", "Study"); 
     }); 
    }) 
    .Value(Model.StudyName != null ? Model.StudyName.ToString() : "") 
) 

इस तरह से व्यूबैग से बचेंगे और सीधे मूल्यों को भरने के लिए फ़ंक्शन का उपयोग करें।

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