2013-04-16 18 views
5

Sto cercando di ottenere alcune visualizzazioni MVC4 da visualizzare nelle schede jQuery. Ecco il mio codice:Schede jQuery con contenuto MVC

<div id="tabs"> 
    <ul> 
     <li><a href="#appone">App One</a></li> 
     <li><a href="#apptwo">App Two</a></li> 
    </ul> 
    <div id="appone"> 
     @{ Html.RenderPartial("~/Views/AppOne/Index.cshtml"); } 
    </div> 
    <div id="apptwo"> 
     @{ Html.RenderPartial("~/Views/AppTwo/Index.cshtml"); } 
    </div> 
</div> 

Il problema è che il contenuto della prima scheda viene visualizzato correttamente ma il secondo è vuoto. Sembra che la vista parziale non sia resa.

C'è un modo per forzare le schede jQuery per aggiornare il contenuto di TUTTE le schede quando la pagina viene caricata, o un modo per forzare la mia vista parziale a eseguire il rendering al caricamento della pagina?

+1

Si dovrebbe richiamare ActionResults per quelli, non alimentando direttamente le viste. Questo è probabilmente il motivo per cui non funziona per te, perché non è in esecuzione nel contesto del framework. –

+0

Sì, lo stavo facendo usando jQuerys load ('AppOne'). Questo ha funzionato, ma stavo avendo problemi con il javascript. Funziona anche con le schede create nel caricatore Ajax, ma la scheda si ricarica con ogni clic, perdendo i dati del modulo. La cache delle schede non funzionava. – Nicros

+1

Se ognuno di essi ha i propri modelli, è sufficiente utilizzare RenderAction anziché RenderPartial. In questo modo puoi dar loro da mangiare un modello tutto loro che si aspettano. Facendolo nel modo in cui lo sono, entrambi rendono il rendering nel contesto del modello che hai a portata di mano in quella vista. –

risposta

4

Ecco il codice che sto lavorando attivamente su questo sta lavorando bene:

Login.cshtml

@{ 
    AjaxOptions optsLogin = new AjaxOptions { UpdateTargetId = "login-tab-login" }; 
    AjaxOptions optsRegister = new AjaxOptions { UpdateTargetId = "login-tab-register" }; 
} 
<section id="login-tabs"> 
    <ul> 
     <li><a href="#login-tab-login">Returning Customers</a></li> 
     <li><a href="#login-tab-register">New Customers</a></li> 
    </ul> 
    @using (Ajax.BeginForm("Login", "Account", optsLogin, new { id = "form-login" })) 
    { 
     <div id="login-tab-login"> 
      @Html.Partial("Account/_Login") 
     </div> 
    } 
    @using (Ajax.BeginForm("Register", "Account", optsRegister, new { id = "form-register" })) 
    { 
     <div id="login-tab-register"> 
      @Html.Partial("Account/_Register") 
     </div> 
    } 
</section> 
<script type="text/javascript"> 
    $(function() { 
     $('#login-tabs').tabs(); 
    }); 
</script> 

mie viste parziali sono nella cartella condivisa in una sottocartella account. Inoltre, ciascuna vista parziale ha il proprio modello. Oltre a questo, l'implementazione è niente di speciale ...

UPDATE

ho aggiunto il codice per implementare Ajax invita le due schede. Il blocco di codice sopra la sezione delle schede contiene gli oggetti AjaxOptions per i due elementi <form>. Il controller ha bisogno di guardare qualcosa di simile:

AccountController.cs

public class AccountController : Controller 
{ 
    ... 
    [HttpGet] 
    public ActionResult Login() 
    { 
     ... 
     return View(); 
    } 

    [HttpPost] 
    public ActionResult Login(LoginModel model) 
    { 
     ... 
     if (ModelState.IsValid) 
      return RedirectToAction("Index", "Home") 
     else 
      return PartialView("/Account/_Login", model); 
    } 

    [HttpPost] 
    public ActionResult Register(RegisterModel model) 
    { 
     ... 
     if (ModelState.IsValid) 
      return RedirectToAction("Index", "Home") 
     else 
      return PartialView("/Account/_Register", model); 
    } 
} 

Il metodo di azione Login GET rende l'intera pagina, comprese le _Layout.cshtml e _ViewStart.cshtml vista. Le mie viste parziali, _Login.cshtml e _Register.cshtml, contengono gli elementi HTML per i moduli di immissione. Ogni visione parziale ha un proprio pulsante di invio:

<input type="submit" value="<Whatever you want to display>" /> 

Poiché ogni chiamata vista parziale è racchiuso in un proprio using (Ajax.BeginForm(...)) blocco e ho dato a ciascuno <form> suo stesso attributo id, posso aggiungere codice JavaScript per dirottare l'evento submit. A seconda di quale tasto submit viene premuto, eseguirà il metodo di azione associato all'azione e al controller specificati nella chiamata Ajax.BeginForm(...). Nel mio caso, se i dati del modulo superano la convalida, il controller reindirizzerà automaticamente a /Home/Index.

Tuttavia, se la convalida non riesce, il metodo di azione sarà sufficiente inviare di nuovo la versione resa della mia vista parziale al browser e metterlo in l'elemento specificato nella proprietà UpdateTargetId nell'oggetto AjaxOptions associato alla <form>. Poiché il valore predefinito InsertionMode è Replace, il motore di visualizzazione sostituirà semplicemente la versione precedente della vista parziale con la nuova versione, completa dei dati del modulo e dei messaggi di convalida, se inclusi.

Gli unici elementi relativi al codice che non ho incluso sono le mie viste parziali, che in realtà non hanno importanza per quanto riguarda la funzionalità delle schede jQuery. Non ho alcun JavaScript aggiuntivo nelle mie viste parziali e il codice aggiuntivo nel AccountController non incluso è specifico per chiamare la mia applicazione console API Web esterna e impostare il cookie di autorizzazione. Sto usando il CDN di Google per le mie dichiarazioni di jQuery e jQuery UI, piuttosto che ospitare localmente JavaScript.

Ci vuole un po 'per avvolgere la testa su quello che devi fare. Una volta ottenuto, però, ce l'hai e la conoscenza è trasferibile. Questo è non WebForms, grazie al cielo.

+0

Stai utilizzando le schede jQuery? Fare qualcosa di stravagante lì? E la tua seconda scheda mostra bene? Deve esserci qualcos'altro che succede per me se questo funziona per te. Lo guarderò. – Nicros

+0

Ho aggiunto la mia chiamata jQuery al codice esistente, ma questo è tutto ciò che serve per far funzionare le schede. Se si desidera che ciascuna scheda rappresenti un modulo, che è quello che sto facendo, è necessario avvolgere ogni DIV in un blocco utilizzando che chiama Ajax.BeginForm (...). Devi solo assicurarti di avere un metodo di azione nel controller per ogni azione del modulo che viene chiamata. –

+0

Le mie schede funzionano ... solo nessun contenuto in quella seconda scheda, anche se so che funziona bene al di fuori delle schede o nella prima scheda. Il mio codice sul lato del rasoio sembra proprio come il tuo ... anche se non sono sicuro di cosa intendi 'avvolgendo ogni DIV in un blocco usando che chiama Ajax.BeginForm' ... forse è quello che mi manca. – Nicros

Problemi correlati