سؤال

أنا جديدة على MVC, ولكن لقد كنت في جميع أنحاء هذا, قراءة جميع الوثائق و كل الأسئلة و كل المشاركات بلوق يمكنني العثور على و كل ما أفعله هو الحصول على ملفوفة تماما حول المحور.

أنا أحاول أن "إنشاء" العمل وعرض.بلدي إدخال البيانات نسبيا على التوالي إلى الأمام و الشائعة:لدي قائمة منسدلة و مربع نص.في حالتي أنا إنشاء مستخدم الاتصال القناة ، المنسدلة مربع يختار بين البريد الإلكتروني و textmsg و مربع النص ثم يدخل معلومات الاتصال ذات الصلة ، إما عن شكلت عنوان البريد الإلكتروني أو رقم الهاتف المحمول.

وهنا (قليلا شكل مبسط) من وجهة نظري الصفحة:

 <tr>
     <td><%= Html.DropDownList("ChannelDescription", Model.ChannelDescription, "Select a Channel", new { id = "ChannelDDL", onchange="ChannelDDLChanged()" })%>
         <br />
         <%= Html.ValidationMessage("ChannelDescription", "Please Select a Channel") %>
      </td>
      <td>
           <%= Html.TextBox("SubscriberNotificationAddr") %> <br />
           <%= Html.ValidationMessage("SubscriberNotificationAddr", "Please enter a contact address or number") %>
       </td>
  </tr>

أنا باستخدام بقوة كتبته ViewData نموذج, بدلا من استخدام ViewDataDictionary.على ChannelDescription العنصر هو SelectList التي يتم تهيئة مع قائمة من الخيارات ولا اختيار.

العرض الأولي من نموذج إدخال البيانات في النموذج ، واستخراج البيانات من شكل المراقب المالي على ما يرام.

مشكلتي هي إذا كانت البيانات تحتوي على خطأ ، مثل mal-شكلت عنوان البريد الإلكتروني أو رقم الهاتف الخليوي, و يجب أن أعود إلى رأي أنا لم ننجح في الحصول على القائمة المنسدلة اختيار يتم إعادة عرض.على ChannelDescription عنصر صوغه في وحدة تحكم مع المستخدم اختيار العنصر المحدد.لدي مجموعة نقاط على خط عرض ، والتحقق من أن العنصر المحدد من قائمة من البنود المختارة تعيين خاصية صحيح, لكنه لا يزال يعرض الافتراضي "اختر القناة".

هذا يبدو وكأنه سيكون حالة شائعة جدا, و لن يكون هذا صعبا.ما الخطأ الذي فعلته ؟

لمعلوماتك هذا مع MVC 1.0 (الإصدار), ويندوز 7, و VS 2008, يعمل تحت Firefox 3.5.2.

هل كانت مفيدة؟

المحلول 2

وكان لي بعض المناقشات مع براد ويلسون، من فريق MVC، وأوضح لي أن كنت سوء فهم الكيفية التي ينبغي أن تستخدم أسلوب مساعد دروبدوونليست (سوء فهم اعتقد قد يكون شائع إلى حد كبير، من ما قرأت ).

وأساسا، سواء كانت تعطيه SelectList في المعلمة اسمه من ViewModel، والسماح لها ببناء القائمة المنسدلة من أنه مع العناصر المناسبة المحدد، أو تعطيه SelectList كمعلمة منفصلة والسماح للمعلمة اسمه ل ViewModel يكون مجرد سلاسل قيمة للعنصر المحدد (ق). إذا كنت تعطيه المعلمة SelectList، فإنه يتوقع أن تكون القيمة اسمه سلسلة أو سلاسل قائمة، وليس SelectList.

وحتى الآن، ViewModel بك ينتهي وجود العنصرين لمادة المفاهيمي واحد في العرض (القائمة المنسدلة). وبالتالي، قد يكون لديك نموذج التي لديها

string SelectedValue {get; set;}
SelectList DropDownElements { get; set;}

وبعد ذلك يمكنك قبل ملء DropDownElements مع الخيارات، ولكن في ضوء النموذج الخاص بك ملزمة، تحتاج فقط للتعامل مع العنصر SelectedValue. ويبدو أن تعمل بشكل جيد جدا بالنسبة لي عندما كنت تفعل ذلك بهذه الطريقة.

نصائح أخرى

بعد عرض الإجابة أعلاه ، أردت التحقق من ذلك, لأن جميع الأمثلة التي رأيتها كان, في الواقع, استخدام ViewDataDictionary بدلا من كتابتها بقوة ViewDataModel.

هكذا فعلت بعض التجارب.لقد شيدت بسيط جدا مفاده أن استخدام عادي ViewDataDictionary ، ومرت القيم في طريق اسمه مفاتيح.استمر العنصر المحدد على ما يرام.ثم قص و لصق هذا الرأي (وحدة تحكم) إلى واحد آخر ، تغيير إلا ما كان من الضروري التحول إلى كتابتها بقوة ViewData نموذج.لو ، و ها ، كما استمرت العنصر المحدد.

ماذا كانت مختلفة بين اختبار بسيط و طلبي ؟ في اختبار, كنت قد استخدمت ببساطة "Html.DropDownList("name", "optionLabel")".ومع ذلك في التطبيق كان في حاجة لإضافة سمات HTML فقط الزائدة المتاحة التي شملت HtmlAttributes تشمل أيضا تحديد قائمة.

اتضح أن DropDownList الزائد مع قائمة مختارة المعلمة كسر!تبحث في تحميلها MVC شفرة المصدر ، عندما DropDownList يسمى مع مجرد اسم أو اسم و optionLabel, ينتهي استرجاع الهدف حدد قائمة من ViewData ثم استدعاء خاص SelectInternal الطريقة المكالمة التالية:

    return SelectInternal(htmlHelper, optionLabel, name, selectList, true /* usedViewData */, false /* allowMultiple */, (IDictionary<string, object>)null /* htmlAttributes */);

إلا أنه إذا دعا مع selectList المعلمة ينتهي التالية:

   return SelectInternal(htmlHelper, optionLabel, name, selectList, false /* usedViewData */, false /* allowMultiple */, htmlAttributes);

الفرق هو أنه في الأولى (والتي سوف تعمل بشكل صحيح) إن "usedViewData" المعلمة غير صحيحة ، بينما في الثانية فهى كاذبة.الذي هو في الواقع حسنا, ولكن يعرض داخلي خلل في SelectInternal الروتينية.

إذا usedViewData باطل ، فإنه يحصل على كائن متغير "الافتراضية" من ViewData نموذج.ومع ذلك ، defaultValue تستخدم على الرغم من أنه هو أيضا سلسلة أو مجموعة من السلاسل, عندما, في الواقع ما عاد من ViewData هو SelectList.(IEnumerable<SelectListItem>).

إذا usedViewData صحيحا ، ثم الافتراضية سوف تكون إما فارغة أو سلسلة.

ثم إذا defaultValue ليست فارغة, ينتهي الذهاب إلى كتلة من التعليمات البرمجية التي تحتوي على هذا:

        foreach (SelectListItem item in selectList) {
            item.Selected = (item.Value != null) ? selectedValues.Contains(item.Value) : selectedValues.Contains(item.Text);
            newSelectList.Add(item);

selectList هو الأصل selectList الذي صدر في ، لذلك العنصر هو SelectListItem (سلسلة نصية ، سلسلة القيمة ، و منطقي مختارة).ولكن selectedValues كانت مستمدة من defaultValue ، ويصبح قائمة SelectLists ليس قائمة من السلاسل.لذا لكل من البنود ، هو الإعداد المحدد العلم استنادا إلى ما إذا كان selectedValues قائمة "يحتوي على" البند.القيمة.حسنا, قائمة SelectLists لن "تحتوي على" سلسلة ، لذلك العنصر.اختيار لم يحصل تعيين.(تصحيح:في الواقع, بعد تتبع مع المصحح ، وجدت أن selectedValues مشتق من defaultValue من قبل "ToString()" دعوة.لذلك هو في الواقع قائمة سلاسل, ولكن بدلا من التي تحتوي على القيم التي نريد ، أنه يحتوي على "النظام.ويب.Mvc.SelectList" - نتيجة تطبيق "ToString()" إلى كائن معقد مثل SelectList.والنتيجة لا يزال هو نفسه - نحن لن تجد قيمة نبحث عنه في تلك القائمة.)

ثم البدائل التي شيدت حديثا "newSelectList" الأصلي "selectList" ، وتشرع في بناء HTML من ذلك.

كما cagdas (أعتذر عن ذبح اسمك ولكن لا أعرف كيفية جعل تلك الأحرف على لوحة المفاتيح الولايات المتحدة) ذكر أعلاه, أعتقد أنني سوف تضطر لبناء بلدي الأسلوب الذي تريد استخدامه في مكان DropDownList HtmlHelper.أعتقد لأن هذا الإصدار 1 و Release2 في بيتا 2, نحن لا يمكن أن نتوقع حقا أي إصلاحات الشوائب ما لم نفعل ذلك بأنفسنا صحيح ؟

راجع للشغل, إذا كنت قد اتبعت لي هذا الآن ، هذا الرمز هو في src\SystemWebMvc\Mvc\Html\SelectExtensions.cs في جميع أنحاء خط 116-136

ونعم أيضا كان لي الكثير من مشاكل في الحصول على دروبدوونليست احترام العنصر المحدد اعطيت له.

يرجى مراجعة بلدي الإجابة على هذا السؤال في . بقدر ما أستطيع أن أتذكر، وهذا هو السبيل الوحيد أتمكن من الحصول على عمل. عن طريق تمرير قائمة عبر ViewData.

ولمعلوماتك، أنا توقفت عن استخدام هذا الأسلوب HtmlHelper. أنا الآن مجرد إخراج <select> و<option> علامات نفسي مع حلقة وتعيين الخاصية selected العلامة option عن طريق التحقق من ذلك بنفسي.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top