2013-08-05 24 views
7

Jestem wykonawczych wyboru listy pudełko w MVC, mimo że uda się uzyskać pożądany wynik, mam wątpliwości w moim podejściu:Asp.Net MVC Checkbox lista

public class AdditionalServicesModel 
{ 
    public IList<SelectListItem> AdditionalServices { get; set; } 
} 

======= ================================================== ================

public class HomeController : Controller 
{ 
    // 
    // GET: /Home/ 

    public ActionResult Index() 
    { 
     AdditionalServicesModel objAdditionalServicesModel = new AdditionalServicesModel(); 

     List<SelectListItem> services = new List<SelectListItem>(); 
     services.Add(new SelectListItem { Text = "service-1", Value = "1", Selected=false }); 
     services.Add(new SelectListItem { Text = "service-2", Value = "2", Selected=false }); 
     services.Add(new SelectListItem { Text = "service-3", Value = "3", Selected=false }); 
     objAdditionalServicesModel.AdditionalServices = services; 

     return View(objAdditionalServicesModel); 
    } 

    [HttpPost] 
    public ActionResult Index(AdditionalServicesModel result) 
    { 
     return RedirectToAction("Thanks", "Home"); 
    } 

    public ActionResult Thanks() 
    { 
     return View(); 
    } 
} 

=========================== ==============================================

@model checkboxes.Models.AdditionalServicesModel 
@{ 
    ViewBag.Title = "Index"; 
    Layout = null; 
} 


@using (Html.BeginForm("Index", "Home", FormMethod.Post)) 
{ 
    for (int i = 0; i < Model.AdditionalServices.Count; i++) 
    {   
     <ul> 
      <li> 
       @Html.CheckBoxFor(m=>Model.AdditionalServices[i].Selected, new { id = "Chk-" + i}) 
       @Html.Label(Model.AdditionalServices[i].Text, new { @for = "Chk-" + i }) 
       @Html.HiddenFor(m => Model.AdditionalServices[i].Text) 
       @Html.HiddenFor(m=> Model.AdditionalServices[i].Value) 
      </li> 
     </ul> 
    } 
    <input type="submit" value="POST to Controller" /> 
} 

1) Dla jednego pola wyboru powinienem utworzyć 2 dodatkowe ukryte pola. Czy istnieje lepsze podejście? Wydaje mi się, że to po prostu źle, aby zrobić tak długą drogę tylko po to, aby wysyłać wartości + wartości w okienkach kontrolnych. O wiele łatwiej byłoby zebrać wartości za pomocą javascript i wysłać je przez Json, ale wtedy nie będę miał dyskretnego sprawdzania poprawności ...

2) Wysyłam wszystkie pola wyboru, gdy potrzebuję wysłać tylko wybrane pola. Czy można to zrobić za pomocą formularzy?

+0

Nadal możesz używać sprawdzania poprawności, wystarczy wywołać sprawdzanie poprawności na obiekcie formularza przed próbą wysłania wybranych opcji z powrotem na serwer. – ps2goat

+0

Czy chodziło Ci o dyskretną walidację, która działa zarówno na kliencie, jak i na serwerze? Czy masz dla mnie przykład? – Alex

+0

nie będzie można użyć tej samej procedury sprawdzania poprawności, jeśli opublikujesz tylko częściowe dane, chyba że utworzysz drugi model, który ma tylko te właściwości, które chcesz zwrócić. W ten sposób zrobi się trochę owłosiony, ponieważ będziesz musiał zsynchronizować modele. Używanie pojedynczego modelu i wysyłanie wszystkich danych z powrotem może być sprawdzone w obu miejscach za pomocą DataAnnotations z modelem, który jest częścią 2 w tym łączu. DataAnnotations są używane w dyskretnym javascriptu i istnieje funkcja Modelstate.IsValid(), którą wywołujesz, gdzie dane zostaną opublikowane. – ps2goat

Odpowiedz

4

Utwórz niestandardową klasę "pole wyboru usług" (wielokrotnego użytku) i utwórz listę lub wyliczalną z nich jako właściwość w swoim AdditionalServicesModel. Jest to prawdopodobnie lepszy pomysł na utworzenie konstruktora modelu, więc nie trzeba przypisywać właściwości modelu wewnątrz kontrolera.

public class ServicesItem 
{ 
    public bool Selected { get; set; } 
    public string Value { get; set; } 
    public string Text { get; set; } 
} 

public class AdditionalServicesModel 
{ 
    public AdditionalServicesModel(IList<ServicesItem> items){ 
     this.AdditionalServices = items; 
    } 

    public IList<ServicesItem> AdditionalServices { get; set; } 
} 

Tworzenie własnego szablonu edytora dodatkowych usług, aby łatwo odwoływać w widoku (nie trzeba dodawać ukryty w tekście, jak tylko wartość i wybranych właściwości zostaną domyślne zbindowanych powrotem do model:

@Html.CheckBoxFor(m => Selected) 
    @Html.LabelFor(m => Text) 
    @Html.HiddenFor(m => Value) 

Wtedy pop edytora szablonów do widoku (niech MVC.net zrobić swoją magię - spojrzeć na znaczniki, aby zobaczyć, co robi):

@Html.EditorFor(m => m.AdditionalServices) 

Następnie skontrolować autom atically bound wartości w twoim kontrolerze:

public class HomeController : Controller 
    { 
     public ActionResult Index() 
     { 
      List<SelectListItem> services = new List<SelectListItem>(); 
      services.Add(new SelectListItem { Text = "service-1", Value = "1", Selected=false }); 
      services.Add(new SelectListItem { Text = "service-2", Value = "2", Selected=false }); 
      services.Add(new SelectListItem { Text = "service-3", Value = "3", Selected=false }); 

      return View(new AdditionalServicesModel(services)); 
     } 

    [HttpPost] 
    public ActionResult Index(AdditionalServicesModel result) 
    { 
     var selectedServicesList = result.AdditionalServices.Where(s => s.Selected); 
     return RedirectToAction("Thanks", "Home"); 
    } 
}