2013-04-16 19 views
5

Próbuję uzyskać niektóre widoki MVC4 do wyświetlania w zakładkach jQuery. Oto mój kod:zakładki jQuery z zawartością MVC4

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

Problem polega na tym, że zawartość pierwszej karty wyświetla się dobrze, ale druga jest pusta. Wygląda na to, że widok częściowy nie jest renderowany.

Czy istnieje sposób wymuszania na kartach jQuery aktualizowania zawartości dla WSZYSTKICH zakładek po załadowaniu strony lub sposobu na wymuszenie renderowania częściowego przy ładowaniu strony?

+1

Powinieneś wywoływać ActionResults dla tych, nie karmiąc bezpośrednio widokami. Pewnie dlatego nie działa on dla ciebie, ponieważ nie jest wykonywany w kontekście frameworka. –

+0

Tak, robiłem to przy użyciu obciążenia jQuerys ("AppOne"). To działało, ale miałem problemy z javascript. Działa również z kartami wbudowanymi w ajax loader, ale karta ładuje się za każdym kliknięciem, tracąc dane formularzy. Buforowanie kart nie działa. – Nicros

+1

Jeśli każdy z nich ma własne modele, wystarczy użyć RenderAction zamiast RenderPartial. W ten sposób możesz nakarmić każdego z nich swoim własnym modelem, którego oczekują. Robiąc to w taki sposób, w jaki masz, obaj oddają się w kontekście modelu, który masz pod ręką w tym widoku. –

Odpowiedz

4

Oto kod mam aktywnie działa na tym działa dobrze:

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> 

Moi częściowe widoki są w folderze udostępnionym w podfolderze konto. Ponadto każdy widok częściowy ma swój własny model. Poza tym, realizacja to nic specjalnego ...

UPDATE

Dodałem kod do wdrożenia Ajax wzywa obu kartach. Blok kodu nad sekcją tabulatorów zawiera obiekty AjaxOptions dla dwóch elementów . Kontroler musi wyglądać tak:

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

Login GET metoda działania czyni całą stronę, w tym _Layout.cshtml i _ViewStart.cshtml widokami. Moje częściowe widoki, _Login.cshtml i _Register.cshtml, zawierają elementy HTML dla formularzy wprowadzania. Każdy częściowy widok ma swój własny przycisk przesyłania:

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

Ponieważ każda częściowa wezwanie widok jest zamknięty w swoim własnym using (Ajax.BeginForm(...)) bloku i dałem każdą <form> swój atrybut id mogę dodać kod JavaScript porwać zdarzenie submit. W zależności od tego, który przycisk zostanie naciśnięty, wykona metodę akcji powiązaną z określoną akcją i kontrolerem w wywołaniu Ajax.BeginForm(...). W moim przypadku, jeśli dane formularza przejdą walidację, kontroler automatycznie przekieruje do /Home/Index.

Jednakże, jeśli uwierzytelnienie nie powiedzie, sposób działania będą po prostu odesłać renderowany wersję mojego częściowym widokiem na przeglądarce i umieścić go w elemencie określonego we właściwości UpdateTargetId w obiekcie AjaxOptions związanego z <form>. Ponieważ domyślnie InsertionMode jest Replace, mechanizm wyświetlania po prostu zastąpi starą wersję częściowego widoku nową wersją, uzupełnioną o dane formularza i komunikaty sprawdzania poprawności, jeśli są zawarte.

Jedyne pozycje związane z kodem, których nie uwzględniłem, to moje widoki częściowe, które tak naprawdę nie mają znaczenia, jeśli chodzi o funkcjonalność kart jQuery. W moich widokach częściowych nie mam dodatkowego kodu JavaScript, a dodatkowy kod w pliku AccountController, który nie został uwzględniony, dotyczy wywoływania mojej zewnętrznej aplikacji konsoli Web API i ustawiania pliku cookie autoryzacji. Używam CDN firmy Google do moich deklaracji jQuery i jQuery UI, zamiast lokalnie obsługiwać JavaScript.

Zapakowanie głowy w to, co musisz zrobić, zajmuje trochę czasu. Ale kiedy już go masz, masz go i możesz przekazać wiedzę. To jest nie WebFormy, dzięki Bogu.

+0

Używasz kart jQuery? Coś w tym fantazyjnego? A twoja druga karta pokazuje się dobrze? Musi mi się coś jeszcze stać, jeśli to ci pomoże. Sprawdzę to. – Nicros

+0

Dodałem moje wywołanie jQuery do istniejącego kodu, ale to wszystko, czego potrzebujesz, aby karty działały. Jeśli chcesz, aby każda karta reprezentowała formularz, co właśnie robię, musisz zawinąć każdy DIV w bloku, który wywołuje Ajax.BeginForm (...). Musisz tylko upewnić się, że masz metodę akcji w kontrolerze dla każdej akcji formularza, która zostanie wywołana. –

+0

Moje karty działają ... po prostu nie ma zawartości na tej drugiej karcie - mimo że wiem, że działa dobrze poza zakładkami lub na pierwszej karcie. Mój kod po stronie brzytwy wygląda tak jak twój ... chociaż nie jestem pewien, co masz na myśli mówiąc "zawijanie każdego DIV w blok, który nazywa Ajax.BeginForm" ... może tego właśnie brakuje. – Nicros

Powiązane problemy