Salve!
Mi piacerebbe creare per hobby una single page application, e così ho aperto il buon visual studio, nuovo progetto MVC3 vuoto, ho inserito jQuery + jQuery UI + unobtrusive plugins.

Vorrei ora qualche consiglio su come usare al meglio le tecnologie a disposizione.

Avete dei link per iniziare?
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,
il metodo .load sarà senz'altro la chiave di volta dell'applicazione.
http://api.jquery.com/load/

E' quello che ti consente di caricare pezzi di markup e iniettarli nella pagina, in seguito all'interazione dall'utente con gli elementi della pagina.

Nel tuo progetto MVC, avrai una view completa di tutti i tag <html>, <body> e tante <div> che userai come contenitori. Poi, creati delle action e altrettante views, che producano solo frammenti di html che verranno inseriti nelle <div> contenitrici grazie al metodo .load.

La principale difficoltà è quella di convertire link e forms in chiamate ajax, ma senza rinunciare alle funzionalità di MVC, come i comodi html helpers tipo Html.ActionLink (per creare link) o Html.EditorFor (per form di modifica dati).

Inizia creando un link nella "single page", al solito modo:

Html.ActionLink("Clicca per caricare il contenuto", "Contenuto")

Questo produrrà una cosa del genere:

<a href="/<i>TuoController</i>/Content">Clicca per caricare il contenuto</a>

Ma tu non vuoi un link così, perché al click ti si ricaricherebbe la pagina. Quindi, seguendo l'approccio unobtrusive, puoi trasformare quel link affinché al click si verifichi una chiamata al metodo .load di jQuery per leggere l'html prodotto dalla action "Contenuto". L'output così ottenuto sarà iniettarlo nella pagina, e la ridirezione che si sarebbe verificata al click dovrà infine essere inibita.

//eseguo una funzione al caricamento di pagina
$(function () {
    //per ogni link...
    $("a").each(function () {
        //leggo l'href
        var href = $(this).attr("href");
        //e lo uso per gestire il click che invocherà il .load e restituirà false affinché la ridirezione non avvenga
        $(this).click(function () { $(this).parent().load(href); return false; });
    });
});


Questo è solo un inizio, ovviamente io non voglio che OGNI link sia sottoposto a questo trattamento. Per esempio potresti contrassegnare solo determinati link, dandogli un attributo personalizzato che indichi, tra l'altro, in qual è l'id dell'elemento contenitore in cui dovrà essere caricato il contenuto:

//assegno un attributo "data-container" 
Html.ActionLink("Carica il contenuto", "Content", null, new Dictionary<string, object> {{"data-container", "<i>idcontenitore</i>"}})

Poi usi il selettore $("a[data-container]") che agirà solo sui link provvisti dell'attributo data-container (o qualsiasi altro nome tu voglia dargli).

Stessa cosa puoi fare per i form.
//eseguo una funzione al caricamento di pagina
$(function () {
    //per ogni form eseguo una funzione
    $("form").each(function () {
        //eseguo una funzione al submit del form
        $(this).submit(function () {
            //leggo la sua action
            var action = $(this).attr("action");
            //mi credo un oggetto vuoto in cui inserirò tutti i valori del form
            var params = {};
            //eseguo una funzione per ogni campo del form
            $(this).find(":input").each(function () {
                //leggo il nome
                var name = $(this).attr("name");
                //e se non è vuoto, lo copio nell'oggetto prima
                if (name != void(0))
                    params[name] = $(this).val();
            });
            //infine eseguo la .load, passando l'oggetto che contiene i valori del form
            $(this).parent().load(action, params);
            //restituisco false in modo che il postback "tradizionale" non avvenga
            return false;
        });
    });
});


MVC riceverà i dati del form come se si trattasse di un normale postback, e quindi continuerai a sfruttare la potenza del model binder di MVC, se hai creato delle view tipizzate.

Potresti incontrare due tipi di problemi:
  • Upload di file. Non c'è modo di farlo in ajax, devi inventarti qualcosa con un iframe nascosto;
  • Link e form aggiunti tramite il metodo .load non verranno a loro volta "rielaborati" per effettuare chiamate ajax. Il codice che ho postato qui sopra infatti va in esecuzione solo una volta al caricamento di pagina. Per risolvere questo problema puoi usare il plugin livequery


ciao,

Enjoy learning and just keep making

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.