2011-12-20 16 views
8

Sto usando ASP .NET MVC 3 e ho un problema interessante da risolvere che spero di avere qualche consiglio su.È possibile chiamare il Razor Compiler a livello di programmazione da un metodo di controllo?

Ho una pagina che ha un numero di div al suo interno. Il contenuto di ogni div cambia nel tempo e quindi attualmente ho un timer per ogni div che esegue una richiesta $ .ajax al server che restituisce un PartialViewResult con i contenuti aggiornati del div. La vista parziale è piuttosto complessa e fa riferimento ad altre viste.

Il problema con questo approccio è che non scala molto bene. Potrebbe essere che ogni utente abbia un sacco di questi timer in esecuzione e con molti utenti il ​​server viene costantemente colpito. Avrei preferito, quindi, effettuare una singola richiesta al server che restituisce, potenzialmente, più contenuto div quindi sarebbe:

div1 { some html } 
div2 { some html } 

...

Poi sul client ho potuto mettere ogni bit di HTML nella posizione corretta sulla pagina.

Ho pensato che quello che potevo fare è restituire JSON dal server ma il mio problema è - come ottengo l'HTML? Al momento il compilatore del rasoio verrà eseguito e trasformerà i miei file cshtml di visualizzazione parziale in HTML, ma se restituisco JSON, è possibile chiamare il compilatore del rasoio a livello di programmazione?

Ho trovato Razor Engine qui: http://razorengine.codeplex.com/ che sembra fare ciò che voglio ma è possibile farlo solo con ASP NET MVC vanilla?

Oppure, visto il problema, c'è un modo migliore per raggiungere il mio obiettivo?

Grazie per qualsiasi aiuto!

+1

Perché non creare un'azione che restituisce un nuovo PartialView che restituisce tutte quelle PartialViews? In questo modo il motore viene chiamato dal posto giusto, cioè la vista. – StuperUser

risposta

5

creare un'azione che ritorna un nuovo PartialView che rende tutte quelle PartialViews. ad es. un'azione:

public PartialViewResult AggregatedAction(args) 
{ 
    return PartialView(); 
} 

con una vista che contiene:

@Html.Action("IndividualAction1", null) 
@Html.Action("IndividualAction2", null) 
@Html.Action("IndividualAction3", null) 

Vedere http://haacked.com/archive/2009/11/18/aspnetmvc2-render-action.aspx per maggiori dettagli.

In questo modo c'è solo una richiesta e il motore di rendering viene chiamato dal posto giusto, cioè la vista.

Quindi, con il risultato, è possibile cercare i vari div e sostituire l'html nel client.

$('div#id1').html('div#id1',$(data)); 
$('div#id2').html('div#id2',$(data)); 

Se la struttura della pagina lo consente, si dovrebbe usare: http://api.jquery.com/load/ (come dice @Jorge) per sostituire tutto il codice HTML con una linea.

$('div#targetDiv').load('Controller\AggregatedAction', anyData); 
+1

Grazie StuperUser! Mi ci sono voluti alcuni minuti per grocare la tua risposta, ma questo funzionerà con un certo fascino - Ho un div nascosto nella pagina che ho impostato come ID di destinazione per l'azione Ajax, all'interno della vista che viene restituita per l'azione che eseguo il ciclo e la metto ciascuna delle div che necessita di aggiornamento e poi in Javascript le sposta nel posto giusto nella funzione di successo – kmp

+1

Eccellente. Non è necessario spostarli con JS nella mark up nella gerarchia se sono posizionati in modo diverso da CSS, quindi è possibile caricare su un div "live" non nascosto e devono essere aggiornati in posizione. – StuperUser

+1

Buon punto, grazie! – kmp

3

Si potrebbero avere due metodi: uno che restituisce HTML e un altro che restituisce JSON.

Oppure, in alternativa creare un ActionResult che i delegati ad una JsonResult if the request is an Ajax request, o un PartialViewResult altrimenti ad esempio:

public class AjaxableResult : ActionResult 
{ 

    private readonly JsonResult _jsonResult; 
    private readonly PartialViewResult _partialViewResult; 

    public AjaxableResult(JsonResult jsonResult, PartialViewResult partialViewResult) 
    { 
    _jsonResult = jsonResult; 
    _partialViewResult = _partialViewResult; 
    }  

    public override void ExecuteResult(ControllerContext context) 
    { 
    if (context.HttpContext.Request.IsAjaxRequest()) { 
     _jsonResult.ExecuteResult(context); 
    } 
    else 
    { 
     _partialViewResult.ExecuteResult(context); 
    } 
    } 
} 
+0

Grazie mille per aver risposto, ma il mio problema è che voglio che sia una singola richiesta AJAX al server che restituisce più elementi HTML da inserire, quindi pensateci come una raccolta di BLOB HTML che poi sul client che ho inserito il posto giusto nella pagina – kmp

1

Perché basta fare voi AJAX chiamato e invece di aspettare un oggetto JSON inviare al client il codice html con un metodo nel controller di ActionResult ricordare che questo tipo di ritorno il codice html del tipo di vista come questo

//this if you want get the html by get 
public ActionResult Foo() 
{ 
    return View(); 
} 

E il client chiamato come questo

$.get('your controller path', parameters to the controler , function callback) 

o

$.ajax({ 
     type: "GET", 
     url: "your controller path", 
     data: parameters to the controler 
     dataType: "html", 
     success: your function 
    }); 

Inoltre è possibile caricare una vista parziale, e rendere in una specifica parte del la tua vista con l'jquery load che non c'è più di un ajax chiamato

+0

"carico jquery che non è più di un ajax chiamato tipo" sbagliato ". Se si passano i dati ad esso come un oggetto JavaScript, verrà utilizzato un POST. '" Il metodo POST viene utilizzato se i dati vengono forniti come oggetto, altrimenti si assume GET. "' Http://api.jquery.com/load/ – StuperUser

+0

Grazie, ma questo è come quello che sto facendo attualmente - Ho un timer in esecuzione sul client che chiama un metodo sul controller che recupera l'HTML e nel successo lo inserisce nella pagina. Il problema è che questo significa che per ogni elemento della pagina che deve essere aggiornato ho bisogno di fare una richiesta AJAX separata – kmp

+0

Grazie non lo sapevo. Ho modificato la mia risposta – Jorge

Problemi correlati