2012-06-11 9 views
5

otrzymuje klasawybrać pozycje z listy <T> w MVC 4 użyciu modelu wiązania

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

to możliwe, aby utworzyć widok, który pozwala użytkownikowi wybrać swoje hobby użyciu wiązania modelu?

Z pewnością będzie możliwe obejrzenie AllHobbies i wygenerowanie dla każdego z nich <input type="checkbox" />, a następnie ręczne powiązanie wybranych wartości w kontrolerze zwrotnym. Wygląda na to, że powinno to być możliwe do zrobienia z powiązaniem modelu, ale nie wiem jak.

Odpowiedz

11

Oczywiście, polecam korzystanie z szablonów edytora.

Załóżmy, że to hobby ma nazwę i logiczną pole wskazujące, czy został on wybrany przez użytkownika:

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

następnie sterownik do zasilania modelu do widoku i przetworzyć formularz:

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

wtedy, zawierającego postać pozwala użytkownikowi wybrać zainteresowania:

@model Person 

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

i odpowiedni szablon edytor, który zostanie automatycznie świadczonych dla każdego elementu kolekcji Hobbies (~/Views/Home/EditorTemplates/Hobby.cshtml -> Zauważ, że nazwa i lokalizacja szablonu jest ważna):

@model Hobby 

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

Dla bardziej zaawansowanych scenariuszy edycji chciałbym zalecamy przejście przez Steven Sanderson na temat blog post na ten temat.

+0

+1, świetne informacje. Klasa 'Hobby' nie ma (i nie powinna) mieć wartości logicznej wskazującej, czy dany użytkownik wybrał ją z perspektywy modelu domeny (jest to oczywiście uproszczony przykład). Czy muszę dodać przejściowe pole logiczne do obiektu, aby je obsłużyć, lub czy istnieje inny sposób wykonania wiązania bez tego dodatkowego pola? –

+4

Nie, twoim błędem jest przekazywanie modelu domeny do widoku. To jest źle. Powinieneś zdefiniować model widoku. Wewnątrz tego modelu widoku będziesz miał boolowską właściwość 'Selected', która pozwoli ci pracować z polami w widoku i pobierać wybrane wartości przez użytkownika. Następnie mapujesz wynik do swojego modelu domeny, aby zrobić to, co musisz z nim zrobić. Zapamiętaj najważniejszą regułę w MVC: akcje kontrolera przechodzą/biorą tylko widok modeli do/z widoków. Nie modele domenowe. Modele widoku to klasy, które zaprojektowano specjalnie w celu spełnienia wymagań danego widoku. –

+0

Czy możesz polecić wzór, aby efektywnie (jak w czasie spędzonym na kodowaniu i testowaniu) mapował między modelem domeny i modelem widoku? Jest to tak naprawdę pierwsza instancja (choć robię bardzo mało rozwoju interfejsu użytkownika), w której nie było żadnej różnicy między tymi dwoma. –

Powiązane problemy