Frage

die Templat Helfer Verwendung in MVC2.0 ich in ein dillema lief, wie die Einzelteile zu erhalten, eine Dropdownlist zu füllen. Ich bin mit einem [UIHint(BadgesDropDown)] Attribute, aber wie werde ich die Listenelemente erhalten, ohne die MVC-Muster zu verletzen, sollte den Controller Ort, um sie in der Viewdata? Sollte der BadgesDropDown.ascx einen Helfer aufgerufen, sie zu erhalten?

Im Moment bin ich gehen für:

BadgesDropDown.ascx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%= Html.DropDownList("", ViewData["Badges"] as IEnumerable<SelectListItem>)%>

Controller

ViewData["Badges"] = new SelectList(SiteRepository.GetBadges(), "RowKey", "BadgeName");

Ist dies der Weg zu gehen?

War es hilfreich?

Lösung

In der MVC 2 eine große neue Methode ... die, wenn verwendet, stützt sich auf die alle Attributdaten.

<%@ 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>

Für diese dort zu arbeiten sind 2 Möglichkeiten. Entweder die UIHint hat, die Quelle der Daten zu liefern, oder die Steuerung muss. Wenn die UIHint tut dann den zu thhe Drop-Down zur Verfügung gestellten Daten festgelegt. Die andere Option ist die Steuerung, die uns die Drop-Down-Daten mit einem anderen Satz von Daten zu wechseln heraus ermöglicht als reqired.

Es gibt einige relevante Beispiele, die ich gefunden:

Nerd-Dinner

[1]: searcch für codeclimber.net.nz und How-to-create-a-Dropdownlist-mit-asp.net-mvc   [2]: bradwilson.typepad.com und Vorlagen-Teil-5-Master-Seite-Vorlagen

Andere Tipps

Es gab in letzter Zeit viele Diskussionen über dieses Thema. Ähnliche Straßensperren sind mit Terminen, Datumsbereichen und Multi-Select-Checkbox Listen festgestellt. Überall möchten Sie vielleicht einen umfangreichen Satz von HTML-Steuerelemente verwenden. Ich habe mit dem Konzept der Kinderviewmodel zu experimentieren, und ich glaube, die Lösung ist sauberer als andere Ansätze, die ich ausprobiert habe.

Das Grundkonzept ist, dass Sie einen kleinen Einblick Modell definieren, die auf eine benutzerdefinierte EditorTemplate eng gekoppelt ist.

In Ihrem Beispiel, würden wir mit einem (Kind) Ansichtsmodell beginnen, die eine einzelne Auswahlliste spezifischen ist:

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));
  }
}

In der Ansicht Modell, das die Dropdown-Liste verwenden möchte, dass Sie das Modell auswählen komponieren (wir sind alle Ansicht Modelle verwenden, oder?):

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" });
    ...
  }

Hinweis: Dies ist ein einfaches Beispiel mit einem festen Satz von Drop-Down-Elementen. Wenn sie aus der Domäne Schicht kommen, die Steuerung übergibt sie in das Ansichtsmodell.

Dann eine Editor Vorlage SelectModel.ascx fügt in Geteilt / 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>

Hinweis: OptionFor ist eine kundenspezifische Erweiterung, die die offensichtlich funktioniert

Der Trick hier ist, dass die ID und der Name gesetzt, um die Verbindung Format verwenden, das die Standard-Modelbinder erwartet. In unserem Beispiel "Priority.Value". So ist die Zeichenfolge basierend Value-Eigenschaft, die als Teil SelectModel definiert ist, wird direkt eingestellt. Der Setter kümmert sich um die Liste der Elemente Aktualisieren der Standard wählen Sie die Option setzen, wenn wir das Formular erneut anzuzeigen benötigen.

Wo dieses „Kind View-Modell“ -Ansatz wirklich glänzt ist komplexer „Steuerauszüge Markup“. Ich jetzt untergeordnete Ansicht Modelle, die einen ähnlichen Ansatz für Multiselect-Listen, Start / Ende Datumsbereiche und Datum + Zeit-Kombinationen folgen.

Sobald Sie diesen Weg gehen, die nächste offensichtliche Frage wird Validierung.

ich am Ende all mein Kind Ansichtsmodell ist mit implementieren eine Standardschnittstelle:

public interface IValidatable
{
  bool HasValue { get; }
  bool IsValid { get; }
}

Dann habe ich eine benutzerdefinierte Validation:

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;
  }
}

Jetzt können Sie nur Attribute auf Eigenschaften setzen, die Kind sind Ansichtsmodell basiert wie jedes skalare Eigenschaft:

[IsValid(ErrorMessage = "Please enter a valid start date/time")]
public DateAndTimeModel Start { get; set; }

Ich implementierte die Lösung, wie das obige Beispiel. Eine Sache ist zu beachten, dass Helfer nur mit den gelieferten Daten, um sie funktionieren sollte, finden Sie unter Ansicht Abhängigkeit

  

Die beste Praxis ist Html zu schreiben   Helfer nicht bewusst von Controllern und   Kontexten. Sie sollten ihre Arbeit tun   nur basierend auf welche Daten geliefert wird   der Anrufer.

Ich bin damit einverstanden auf die obige Aussage. Es ist nur so, dass eine Menge Arbeit getan werden muss, wenn sie auf die regelmäßige ASP.Net Entwicklung verglichen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top