2010-08-29 12 views
8

Effettuo il porting di un'applicazione di ricerca da ASP classico a ASP.NET MVC2. Una delle pagine hte è un modulo di ricerca popolato dinamicamente suddiviso in 4 categorie, ciascuna con 2 righe.ASP.NET MVC - Compilazione dinamica di un modulo tramite il database

Il client è in grado di deselezionare le opzioni per ciascuna di queste categorie. Quando ciò accade, ogni categoria viene ripopolata in modo dinamico dall'alto al basso, da sinistra a destra. La persona che ha programmato la versione ASP classica ha configurato una subroutine che ha cercato nel database (che ha un campo booleano per ogni campo di ricerca) e quindi ha restituito un array. Quindi ha preso la matrice e ha chiamato un'altra subroutine che ha fatto il looping della matrice e ha quindi generato ciascuna delle categorie.

In questo momento, l'unica cosa che posso pensare è creare un modello che abbia metodi per ciascuna delle categorie, ognuna delle quali restituisce una lista. Un semplice esempio potrebbe essere:

class SearchPageOrganizer { 

    // Declare SearchFields object 
    private SearchFields fields; 

    // Contructor; instantiates SearchFields object 
    public SearchPageOrganizer(SearchFields searchFields) { 
     this.fields = searchFields; 
    } 

    // Gets a list of fields active in the characteristics category 
    public List<String> GetCharactersticsList() { 
     List<String> list = new List<String>(); 

     // Check if the Color field is active 
     if (fields.Color) { 
      list.Add("Color"); 
     } 

     // Check if the Size field is active 
     if (fields.Size) { 
      list.Add("Size"); 
     } 

     // Return the list 
     return list; 
    } 
} 

Allora che ho potuto fare è suddiviso l'elenco in base alle dimensioni di ogni riga, e quindi ciclicamente ogni lista e chiamare un controllo utente che è in grado di rendere il codice HTML dinamicamente basato su un parametro di nome.

Il problema con questa tecnica è che, per qualche strana ragione, mi sembra che non lo sto facendo nel modo più semplicistico. Per chi legge questo, c'è un modo più semplice con cui implementare questo?

Grazie!

+0

Ho visto "teh" un milione di volte prima, ma mai "hte" - +1 per quello! :-) – DaveDev

+0

Purtroppo, lo faccio tutto il tempo :(. – Swamp56

+0

Solo per riassumere e vedere se ho capito bene ... Vuoi costruire un modulo che elenca le categorie e ognuna di queste categorie ha un elenco di categorie (ognuno con una casella di controllo) sotto di loro.Una volta che si seleziona uno di questi articoli di categoria, è necessario ricaricare tutte le categorie e gli articoli della categoria? – Peter

risposta

0

Come aggiungere gli elenchi utilizzando JavaScript (jQuery) sul lato client quando richiesto? I dati possono essere compilati utilizzando una chiamata Ajax. Una volta che tutti i campi sono stati riempiti e l'utente invia, il metodo di azione può prendere tutti i parametri in entrata ed eseguire una ricerca basata su questo.

1

Questo è qualcosa che ho voluto indagare per qualche tempo. Avendo dilettato in Rails, mi sono rovinato con la vista vincolante per la modella.

Sembra che ci sia un helper nello spazio MVC chiamato Html.EditorForModel(). Questo helper genera un modulo per il modello a cui è vincolata la vista. Non sono esattamente sicuro di cosa farebbe nella tua situazione, ma sicuramente sarebbe interessante vedere l'output e forse potrebbe darti qualche idea per un'implementazione personale.

Buona fortuna!

1

Ecco cosa consiglierei. Crea un div che contiene il contenuto dinamico e metti quel contenuto in una vista parziale. In questo caso ci sarebbe una vista parziale chiamato Products.ascx

<div id="ProductsContent"> 
    <% Html.RenderPartial("Products"); %> 
</div> 

chiamare una funzione JavaScript quando una casella di controllo categoria viene cliccato.

<input id="Category_1" type="checkbox" onclick="CategoryCheckChanged(1)" /> 
<input id="Category_2" type="checkbox" onclick="CategoryCheckChanged(2)" /> 
<input id="Category_3" type="checkbox" onclick="CategoryCheckChanged(3)" /> 

utilizzare jQuery per rilevare il valore della casella di controllo, quindi inviare al server. Nell'esempio seguente il nome del mio controller si chiama Products. Le informazioni restituite dal server sono la vista parziale aggiornata, che sostituisce il contenuto div.

function CheckChanged(id) 
{ 
    var bChecked = $("#Category_"+id).attr("checked"); 

    var value = 0; 
    if(bChecked) value=1; 

    $.post('<%= Url.Action("CategoryChanged","Products") %>' 
     , { value: value, categoryid: id } 
     , function(data) { 
      if (data.success) { 
       alert("Sweet !") 
       //update the div with the new content 
       $('#ProductsContent').html(data.newcontent); 
      } 
      else { 
       alert("Bummer:" + data.msg); 
      } 

     }, "json"); 

} 

Qui è la funzione CategoryChanged in ProductsController

[HttpPost] 
    public ActionResult CategoryChanged(int value, int id) 
    { 
    try 
    { 
     //Save the change to the database 
     SaveChangedCategoryValueToDatabase(id,value); 

     //Create your View Model 
     MyProductsViewModel vm = new MyProductsViewModel(); 

     return Json(new { success = true, newcontent = 
      MyViewHelper.RenderPartialToString(this.ControllerContext, 
      "~/Views/Products/Products.ascx", 
      new ViewDataDictionary(vm), new TempDataDictionary()) }); 

    } 
    catch(SystemException ex) 
    { 
     return Json(new { success = false, msg = ex.Message }); 
    } 

    } 

e infine ... La funzione di supporto che prende rende una vista parziale di una stringa.

+0

RenderParitalToString è piuttosto lento (io l'ho usato) .Quando abbiamo convertito da MVC 1 a 2 abbiamo dovuto scaricare l'approccio renderpartialtostring. Ajax.BeginForm è molto più pulito e sostituisce o aggiunge automaticamente nella vista restituita dall'azione, inoltre è possibile eseguire javascript dopo che il nuovo contenuto è stato caricato in posizione per qualsiasi post-elaborazione. – Josh

0

Si consiglia di utilizzare i moduli Ajax incorporati con MVC 2. È possibile avere controlli parziali basati sul modello passato a loro. Il tuo approccio sarebbe qualcosa come questo, più o meno:

In primo luogo, il controller

public PartialViewResult MySearchControl() 
{ 
    //initialize the model 

    return new PartialView(model) 
} 

[HttpPost] 
public PartialViewResult MySearchControl(MyModel model) 
{ 
    //do work, repopulate the model 

    return new PartialView(model) 
} 

Poi, nella vista, si avrebbe qualcosa di simile.

<% using (Ajax.BeginForm("MySearchControl", "MySearch", 
    new { }, 
    new AjaxOptions() { 
     HttpMethod = "Post", 
     InsertionMode = InsertionMode.Replace, 
     UpdateTargetId = "searchFormWrapper", 
     OnSuccess = "doMoreWork" 
     }, new { })) 
{ %> 

<div id="searchFormWrapper"> 
    <% Html.RenderAction<MySearchController>(x => x.MySearchControl()); %> 
</div> 

<input type="submit" id="mySubmitButton" value="submit" /> 

<% } %> 

<script type="text/javascript"> 
    function doMoreWork() 
    { 
     // do anything needed after content is updated here 
    } 
</script> 

Ora, se avete bisogno di una casella di controllo a fuoco il presentare, è possibile utilizzare un po 'di jQuery magia

<script type="text/javascript"> 
    $(function() { 
     $('.checkBoxClassSelector').live('change', new function(){ 
      $('#mySubmitButton').click(); 
     }); 
    }); 
</script> 

il metodo dal vivo in jQuery farà in modo che l'azione è collegata a tutte le attuali e future istanze della classe se la dai a tutte le checkbox nella tua vista parziale. Faranno postare il modulo ajax, che restituirà la vista parziale - riscritta in base al modello aggiornato e sostituirà il contenuto del div.

Il vantaggio di questo lato puramente client è che puoi far sì che MVC faccia il suo lavoro con il tuo modello e non debba preoccuparsi di formattazione o modifica di un gruppo di javascript per modificare il modo in cui tutto appare o funziona. Basta cambiare la visualizzazione e tutto funziona automaticamente.

Problemi correlati