2012-06-11 18 views
5
Bindung

Bei einer Klasse4 unter Verwendung von Modell

public class Person 
{ 
    // Some general properties 

    public List<Hobby> Hobbies { get; set; } 
} 

public class Hobby 
{ 
    // Some properties e.g. Name, etc. 
} 

static List<Hobby> AllHobbies { get; } 

Ist es möglich, eine Ansicht zu erstellen, die der Benutzer seine Hobbys auswählen kann mit Modell verbindlich?

Es wäre sicherlich möglich, in der Ansicht AllHobbies zu durchlaufen und jeweils <input type="checkbox" /> rendern, dann die ausgewählten Werte von Hand in den Postback-Controller verdrahten. Es scheint, dass dies mit Modellbindung machbar sein sollte, aber ich sehe nicht wie.

Antwort

11

Sicher, ich würde Ihnen empfehlen, Editor-Vorlagen zu verwenden.

Nehmen wir an, ein Hobby, einen Namen und ein boolean Feld hat der angibt, ob es durch den Benutzer ausgewählt wurde:

public class Hobby 
{ 
    public string Name { get; set; } 
    public bool Selected { get; set; } 
} 

dann ein Controller das Modell in der Ansicht zu füttern und zu verarbeiten, um die Formulareinreichung:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     var person = new Person 
     { 
      Hobbies = new[] 
      { 
       new Hobby { Name = "hobby 1" }, 
       new Hobby { Name = "hobby 2", Selected = true }, 
       new Hobby { Name = "hobby 3" }, 
      }.ToList() 
     }; 
     return View(person); 
    } 

    [HttpPost] 
    public ActionResult Index(Person person) 
    { 
     var selectedHobbies = person 
      .Hobbies 
      .Where(x => x.Selected).Select(x => x.Name); 
     string message = string.Join(",", selectedHobbies); 
     return Content("Thank you for selecting: " + message); 
    } 
} 

dann eine Ansicht, die die Form enthält, so dass der Benutzer Hobby auszuwählen:

@model Person 

@using (Html.BeginForm()) 
{ 
    <h2>Hobbies</h2> 
    @Html.EditorFor(x => x.Hobbies) 
    <button type="submit">OK</button> 
} 

und eine Editor Vorlage entspricht, die für jedes Element der Hobbies Sammlung automatisch gerendert werden (~/Views/Home/EditorTemplates/Hobby.cshtml -> Hinweis, dass der Name und Speicherort der Vorlage wichtig ist): erweiterte Bearbeitungsszenarien

@model Hobby 

<div> 
    @Html.LabelFor(x => x.Selected, Model.Name) 
    @Html.HiddenFor(x => x.Name) 
    @Html.CheckBoxFor(x => x.Selected) 
</div> 

Ich will uns Ich empfehle Ihnen, die Steven Sanderson's blog post zu diesem Thema zu gehen.

+0

+1, tolle Infos. Die 'Hobby'-Klasse hat jedoch keinen Booleschen Wert (und sollte dies auch nicht), der anzeigt, ob ein bestimmter Benutzer ihn aus der Perspektive des Domänenmodells ausgewählt hat (dies ist ein vereinfachtes Beispiel). Muss ich dem Objekt ein transientes boolesches Feld hinzufügen, um dies zu unterstützen, oder gibt es eine andere Möglichkeit, die Bindung ohne dieses zusätzliche Feld durchzuführen? –

+4

Nein, Ihr Fehler besteht darin, dass Sie ein Domänenmodell an Ihre Ansicht übergeben. Das ist falsch. Sie sollten ein View-Modell definieren. Innerhalb dieses View-Modells haben Sie eine boolesche 'Selected'-Eigenschaft, mit der Sie mit den Checkboxen innerhalb der View arbeiten und die ausgewählten Werte vom Benutzer abrufen können. Dann ordnen Sie das Ergebnis Ihrem Domänenmodell zu, um alles zu tun, was Sie damit tun müssen. Erinnern Sie sich an die wichtigste Regel in MVC: Controller-Aktionen übergeben/nehmen nur Ansichtsmodelle zu/von Ansichten. Keine Domänenmodelle. Ansichtsmodelle sind Klassen, die speziell für die Anforderungen der jeweiligen Ansicht entworfen wurden. –

+0

Können Sie ein Muster für die effiziente Zuordnung von Domänenmodell und Ansichtsmodell (z. B. in Bezug auf Zeitaufwand für das Codieren und Testen) empfehlen? Dies ist eigentlich die erste Instanz (obwohl ich sehr wenig UI-Entwicklung), wo es einen Unterschied zwischen den beiden gab. –

Verwandte Themen