2013-08-05 18 views
7

sto implementando elenco casella di controllo in MVC, anche se riesco a ottenere il risultato desiderato, ho un dubbio nel mio approccio:Asp.Net MVC Casella elenco

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) Per una casella di controllo dovrei creare 2 campi nascosti aggiuntivi. C'è un approccio migliore? Mi sembra semplicemente sbagliato fare così tanto tempo solo per inviare valori di spunta + nomi, sarebbe molto più facile raccogliere i suoi valori con javascript e inviarlo via Json, ma poi non avrò una validazione discreta ...

2) Invio tutte le caselle di controllo mentre devo inviare solo le caselle selezionate. C'è un modo per farlo con i moduli post?

+0

È ancora possibile utilizzare la convalida, è sufficiente richiamare la convalida sull'oggetto modulo prima di provare a inviare nuovamente le opzioni selezionate al server. – ps2goat

+0

Intendevi una convalida non invadente che funziona sia su client che su server? Hai un esempio per me? – Alex

+0

non sarà possibile utilizzare la stessa convalida se si inviano solo dati parziali indietro, a meno che non si crei un secondo modello con solo le proprietà che si desidera restituire. Sarà un po 'peloso farlo in quel modo, però, perché dovrai mantenere i modelli sincronizzati. L'utilizzo di un modello singolo e la pubblicazione di tutti i dati possono essere convalidati in entrambe le posizioni utilizzando le NoteAnnotations con il modello, che è la parte 2 di quel collegamento. Le NoteAnnotations sono usate in javascript non invadente, e c'è una funzione Modelstate.IsValid() che chiami dove vengono pubblicati i dati. – ps2goat

risposta

4

Creare una classe 'voce di casella di controllo' personalizzata (riutilizzabile) e creare una lista o enumerabile di essi come proprietà in AdditionalServicesModel. Inoltre, è probabilmente una migliore idea creare un costruttore del modello in modo da non dover assegnare le proprietà del modello all'interno del controller.

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

Creare un modello editor personalizzato per i servizi aggiuntivi, per fare riferimento facilmente nella vista (non c'è bisogno di aggiungere un nascosto per il testo, in quanto solo il valore e le proprietà selezionate saranno di default binded nuovo al modello:

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

poi pop l'editor di modelli nella vostra vista (diciamo MVC.net fare la sua magia - avere uno sguardo al markup per vedere cosa fa):

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

quindi ispezionare l'autom valori legati dal punto di vista nel controller:

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