MVC قالب المساعد - القائمة المنسدلة
-
10-07-2019 - |
سؤال
باستخدام قالب المساعدين في MVC2.0 ركضت إلى dillema, كيفية الحصول على العناصر لملء dropdownlist.أنا باستخدام [UIHint(BadgesDropDown)]
السمة ، ولكن كيف يمكنني الحصول على قائمة البنود دون انتهاك نمط MVC, يجب أن تحكم في ViewData?يجب أن BadgesDropDown.ascx
استدعاء مساعد الحصول عليها ؟
الآن أنا ذاهب ل:
BadgesDropDown.ascx
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%= Html.DropDownList("", ViewData["Badges"] as IEnumerable<SelectListItem>)%>
تحكم
ViewData["Badges"] = new SelectList(SiteRepository.GetBadges(), "RowKey", "BadgeName");
هل هذا هو الطريق للذهاب ؟
المحلول
في MVC 2 ملعقة كبيرة طريقة جديدة...والتي إذا استخدمت يعتمد على جميع البيانات السمة.
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<glossaryDB.EntityClasses.AssociationEntity>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Association: Edit
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server">
<h3>Association: Edit</h3>
<% using (Html.BeginForm()) { %>
<fieldset style="padding: 1em; margin: 0; border: solid 1px #999;">
<%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>
<%= Html.EditorForModel() %>
<input type="submit" value=" Submit " />
</fieldset>
<% } %>
<p><%= Html.ActionLink("Details", "Index") %></p>
</asp:Content>
لهذا العمل هناك 2 الخيارات.إما UIHint أن توفر مصدر البيانات أو يجب أن تحكم.إذا كان UIHint لا ثم البيانات المقدمة إلى thhe المنسدلة هو ثابت.الخيار الآخر هو المراقب الذي يسمح لنا بالانتقال من القائمة المنسدلة البيانات مع مجموعة مختلفة من البيانات reqired.
هناك بعض الأمثلة وجدت:
الطالب الذي يذاكر كثيرا العشاء
[1]:searcch على codeclimber.صافي.نيوزيلندي و كيف إلى إنشاء-a-dropdownlist مع asp.صافي-mvc [2]:bradwilson.typepad.com والقوالب-جزء-5-ماجستير-الصفحة قوالب
نصائح أخرى
كان هناك الكثير من النقاش حول هذا الموضوع في الآونة الأخيرة.مماثلة حواجز الطرق التي واجهتها مع التواريخ ، تاريخ نطاقات متعددة حدد خانة الاختيار قوائم.في أي مكان قد ترغب في استخدام مجموعة غنية من تحكم html.لقد تم تجريب مع مفهوم الطفل ViewModels و أعتقد أن الحل هو أنظف من مناهج أخرى لقد حاولت.
المفهوم الأساسي هو أن تعريف صغير نموذج عرض هذا عن كثب بالإضافة إلى مخصص EditorTemplate.
في المثال الخاص بك ، سوف تبدأ مع (الطفل) ViewModel محددة من واحد اختر من القائمة:
public class SelectModel
{
#region SelectModel(string value, IEnumerable<SelectListItem> items)
public SelectModel(string value, IEnumerable<SelectListItem> items)
{
_value = value;
Items = new List<SelectListItem>(items);
_Select();
}
#endregion
// Properties
public List<SelectListItem> Items { get; private set; }
public string Value
{
get { return _value; }
set { _value = value; _Select();}
}
private string _value;
// Methods
private void _Select()
{
Items.ForEach(x => x.Selected = (Value != null && x.Value == Value));
}
}
في ضوء النموذج الذي يريد استخدام القائمة المنسدلة يمكنك إنشاء تحديد نموذج (كلنا باستخدام عرض نماذج, صحيح؟):
public class EmailModel
{
// Constructors
public EmailModel()
{
Priority = new SelectModel("normal", _ToPrioritySelectItems());
}
// Properties
public SelectModel Priority { get; set; }
// Methods
private IEnumerable<SelectListItem> _ToPrioritySelectItems()
{
List<SelectListItem> result = new List<SelectListItem>();
result.Add(new SelectListItem() { Text = "High", Value = "high" });
...
}
ملاحظة هذا مثال بسيط مع مجموعة ثابتة من العناصر المنسدلة.إذا كانت قادمة من طبقة المجال وحدة تحكم يمر بها في ViewModel.
ثم إضافة محرر قالب SelectModel.ascx في مشترك/EditorTemplates
<%@ Control Inherits="System.Web.Mvc.ViewUserControl<SelectModel>" %>
<div class="set">
<%= Html.LabelFor(model => model) %>
<select id="<%= ViewData.ModelMetadata.PropertyName %>_Value" name="<%=ViewData.ModelMetadata.PropertyName %>.Value">
<% foreach (var item in Model.Items) { %>
<%= Html.OptionFor(item) %>
<% } %>
</select>
</div>
ملاحظة:OptionFor هو العرف التمديد التي لا واضح
الحيلة هنا هي أن الهوية واسم يتم تعيين باستخدام مركب شكل الافتراضي ModelBinder تتوقع.في المثال "الأولوية.قيمة".لذا السلسلة على أساس قيمة الممتلكات التي يتم تعريفها بأنها جزء من SelectModel مباشرة.واضع يعتني تحديث قائمة البنود تعيين الافتراضي حدد الخيار إذا نحن بحاجة إلى عرض النموذج.
أين هذا "الطفل نموذج عرض" نهج يضيء حقا هو أكثر تعقيدا "السيطرة على قصاصات من العلامات".لدي الآن الطفل عرض النماذج التي تتبع نفس نهج متعدد القوائم بداية/نهاية نطاقات تاريخ و التاريخ + الوقت تركيبات.
في أقرب وقت كما كنت السير في هذا المسار التالي السؤال واضح يصبح التحقق من الصحة.
لقد انتهى الأمر بعد كل طفلي ViewModel هو تنفيذ واجهة قياسية:
public interface IValidatable
{
bool HasValue { get; }
bool IsValid { get; }
}
ثم لدي مخصص ValidationAttribute:
public class IsValidAttribute : ValidationAttribute
{
// Constructors
public IsValidAttribute()
{
ErrorMessage = "(not valid)";
}
// Properties
public bool IsRequired { get; set; }
// Methods
private bool Is(object value)
{
return value != null && !"".Equals(value);
}
public override bool IsValid(object value)
{
if (!Is(value) && !IsRequired)
return true;
if (!(value is IValidatable))
throw new InvalidOperationException("IsValidAttribute requires underlying property to implement IValidatable");
IValidatable validatable = value as IValidatable;
return validatable.IsValid;
}
}
الآن يمكنك فقط وضع السمات على خصائص الطفل ViewModel على أساس مثل أي العددية الملكية:
[IsValid(ErrorMessage = "Please enter a valid start date/time")]
public DateAndTimeModel Start { get; set; }
لقد نفذت الحل كما في المثال أعلاه.شيء واحد أن نلاحظ أن المساعدين يجب أن تعمل فقط مع البيانات المقدمة ، عرض التبعية
أفضل الممارسات في كتابة Html المساعدين علم من وحدات التحكم ، السياقات.ينبغي القيام بعملهم تستند فقط على البيانات التي يتم توفيره من قبل المتصل.
أنا أوافق على ما سبق بيانه.انها مجرد أن هناك الكثير من العمل يجب القيام به عند مقارنة العادية ASP.Net التنمية.