2011-10-14 13 views
20

Próbuję użyć wywołania Ajax (jak sądzę), aby zaktualizować wartość mojego modelu, a następnie uwzględnić tę nową wartość w widoku. Używam tego do celów testowych w tej chwili.Aktualizowanie widoku ze zmianami modelu za pośrednictwem Ajax Post - MVC3

Oto opis:

MODEL

public class MyModel 
{ 
    public int Integer { get; set; } 
    public string Str { get; set; } 
} 

KONTROLER

public ActionResult Index() 
    { 
     var m = new MyModel(); 
     return View("Test1", m); 
    } 

    [HttpPost] 
    public ActionResult ChangeTheValue(MyModel model) 
    { 
     var m = new MyModel(); 
     m.Str = model.Str; 
     m.Str = m.Str + " Changed! "; 
     m.Integer++; 

     return View("Test1", m); 

    } 

WIDOK

@model Test_Telerik_MVC.Models.MyModel 
@using Test_Telerik_MVC.Models 
@{ 
    ViewBag.Title = "Test1"; 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 
<h2> 
    Test1</h2> 
@if (false) 
{ 
    <script src="~/Scripts/jquery-1.4.4.min.js" type="text/javascript"></script> 
    <script src="~/Scripts/jquery-ui.min.js" type="text/javascript"></script> 
} 
<h2> 
    ViewPage1 
</h2> 

<div> 
    <input type="button" onclick="changeButtonClicked()" id="changeButton" value="Click Me!" /> 
    <input type="text" value="@Model.Str" class="txt" id="str" name="Str"/> 
    <div></div> 
</div> 

<script type="text/javascript"> 

    function changeButtonClicked() { 
     var url = '@Url.Action("ChangeTheValue", "Test1")'; 
     var data = '@Model'; 
     $.post(url, data, function (view) { 
      $("#Str").value = '@Model.Str'; 
     }); 
    } 

</script> 

Zasadniczo widok renderuje przycisk z polem tekstowym. Moim jedynym celem jest po prostu wyświetlenie wartości mojego modelu (właściwość Str) w polu tekstowym.

Próbowałem różnych kombinacji funkcji changeButtonClicked() bezskutecznie. Test1 to nazwa mojego kontrolera. Nie rozumiem, kiedy debuguję, działanie kontrolera uruchamia się i ustawia moje wartości poprawnie. Jeśli wstawię punkt przerwania w sekcji "@ Model.Str" znacznika wejściowego, to pokaże mi, że mój @ Model.Str jest równy Zmienionej! który jest poprawny. Jednak, gdy tylko funkcja powodzenia zostanie uruchomiona w javascript, wartość powraca do pierwotnej wartości.

Mogę sprawić, żeby działało, zmieniając typ danych wejściowych, aby je przesłać i zawinąć w sekcji @ Html.BeginForm(), ale zastanawiam się, czy/jak to zrobić? Czy jest to jedyny sposób, aby to osiągnąć?

Dzięki

Odpowiedz

27

Pierwszą rzeczą w jQuery właściwy sposób ustawić wartość na wejściu jest użycie

$("#Str").val(@Model.Str); 

Dalej przyjrzymy sterownika, w wyniku działania Poczty jesteś zwrócenie całego widoku w twoim wywołaniu ajaxowym. Oznacza to, że wszystkie html, odniesienia do skryptów i javascript są zwracane w żądaniu postu jQuery. Ponieważ wszystko, co próbujesz zaktualizować, jest wartością wejścia o nazwie str, po prostu zwrócę tę wartość jako json i nic więcej.

[HttpPost] 
public ActionResult ChangeTheValue(MyModel model) 
{ 
    var m = new MyModel(); 
    m.Str = model.Str; 
    m.Str = m.Str + " Changed! "; 
    m.Integer++; 

    return Json(m.Str); 

} 

Następny chciałbym umieścić wejść HTML w jQuery więc można szeregować model dla Ciebie, a następnie można zmienić jquery kod pocztowy, aby być:

function changeButtonClicked() { 
    var url = '@Url.Action("ChangeTheValue", "Test1")'; 
    $.post(url, $('form').serialize(), function (view) { 
     $("#Str").val(view); 
    }); 
} 

Wszystkie serialize robi koduje dane wejściowe w twojej postaci w łańcuch i jeśli wszystko jest poprawnie nazwane, aps.net zwiąże to z powrotem do twojego modelu.

Jeśli chcesz, aby Twoja trasa obsługiwała zarówno wywołania ajax, jak i pełne żądania, możesz użyć funkcji IsAjaxRequest asp.net do przetestowania żądania i zwrócenia różnych wyników w zależności od tego, czy żądanie jest ajaxowe, czy nie. Można by zrobić coś takiego w swoim kontrolerze:

[HttpPost] 
public ActionResult ChangeTheValue(MyModel model) 
{ 
    var m = new MyModel(); 
    m.Str = model.Str; 
    m.Str = m.Str + " Changed! "; 
    m.Integer++; 

    if (Request.IsAjaxRequest) { 
     return Json(m.Str); 
    } 
    else { 
     return View("Test1", m); 
    } 
} 

W ActionResult powyżej robisz wszystko, co robił wcześniej, ale teraz testują typ żądania i jeśli to ajax wrócisz wynik JSON swojej wartości ciągu. Jeśli żądanie nie pochodziło z wywołania ajax, cały widok (html, skrypty itp.) Powraca do wyświetlania w przeglądarce.

Mam nadzieję, że to pomaga i jest tym, czego szukałeś.

+0

Mate, to świetnie. Przejdę przez to, co powiedziałeś później, i dam ci znać. Mam nadzieję, że to, co opisałeś, działa. Pozdrawiam – Jason

+1

ok, mam to działa. JSon, jak mówisz, jest drogą do zrobienia w tym przypadku. Jednak ustawienie konkretnej wartości nadal oznacza, że ​​mój obiekt "Model" nigdy nie zawiera zaktualizowanych wartości? Więc jeśli powiem o tym w innym zdarzeniu (powiedzmy po wystrzeleniu), @ Model.Str w rzeczywistości nie zawiera nowej wartości. Aby do tego doszło, muszę przesłać? Dziękuję za odpowiedź. To odpowiada na moje pierwsze pytanie. – Jason

+0

Jeśli chcesz uzyskać najnowszą wartość swoich wejść, będziesz chciał uzyskać je z samego wejścia, możesz to uzyskać za pomocą jQuery $ (# Str) .val(). W przeciwnym razie, jeśli używasz Model.Str gdzieś indziej w kodzie javascript, ta wartość Model.Str jest ustawiana, gdy strona ładuje się po raz pierwszy i nigdy nie zostanie zaktualizowana, chyba że wykonasz pełne odświeżenie strony. – ajrawson

Powiązane problemy