2011-10-14 42 views
20

Estoy tratando de usar una llamada Ajax (creo) para actualizar el valor de mi modelo y luego tener ese nuevo valor reflejado en la vista. Solo estoy usando esto para propósitos de prueba por el momento.Actualización de la vista con cambios de modelos a través de Ajax Post - MVC3

Aquí está el panorama:

MODELO

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

CONTROLADOR

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

    } 

VISTA

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

Básicamente, la vista representa un botón con un cuadro de texto. Mi único objetivo es simplemente mostrar el valor de mi modelo (propiedad Str) en el cuadro de texto.

He intentado varias combinaciones de la función changeButtonClicked() en vano. Test1 es el nombre de mi controlador. Lo que no entiendo es cuando lo depuro, la acción del controlador dispara y establece mis valores correctamente. Si coloco un punto de interrupción en la sección "@ Model.Str" de la etiqueta de entrada, ¡me muestra que mi @ Model.Str es igual a Changed! cual es correcta. Sin embargo, tan pronto como mi función de éxito se activa en el javascript, el valor vuelve a su valor original.

Puedo hacerlo funcionar cambiando el tipo de entrada para enviar y envolverlo en una sección @ Html.BeginForm(), pero me pregunto si/cómo hacerlo así? ¿O es un envío la única forma de lograrlo?

Gracias

Respuesta

27

primera hora de la jQuery la forma correcta de establecer un valor de una entrada es utilizar

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

A continuación vamos a ver en el controlador, en el resultado de la acción del anuncio está devolviendo la vista completa en tu llamada ajax. Eso significa que todos los html, referencias de scripts y javascript se devuelven en su solicitud de publicación de jquery. Como todo lo que intentas actualizar es el valor de la entrada llamada str, simplemente devolvería ese valor como json y nada más.

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

} 

A continuación, me coloque sus entradas html en una para que pueda tener jQuery serializar su modelo para usted y entonces usted puede cambiar su código postal jQuery ser:

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

Toda la serialización está haciendo está codificando las entradas en su forma en una cadena y si todo se llama apropiadamente, aps.net lo vinculará a su modelo.

Si necesita que su ruta maneje tanto las llamadas ajax como las solicitudes completas, puede usar la función IsAjaxRequest de asp.net para probar la solicitud y devolver resultados diferentes dependiendo de si la solicitud es ajax o no. Se podría hacer algo como esto en su controlador:

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

En el ActionResult por encima de que está haciendo todo lo que hizo antes, pero ahora se está probando el tipo de solicitud y si es ajax que devolver un resultado JSON de su valor de cadena. Si la solicitud no proviene de una llamada ajax, la vista completa (html, scripts, etc.) se devuelve para mostrarse en el navegador.

Espero que esto te ayude y sea lo que estabas buscando.

+0

Compañero, eso es increíble. Voy a repasar lo que has dicho un poco más tarde y dejarte saber. Espero que lo que has descrito funcione. Cheers – Jason

+1

ok, lo tengo funcionando. JSon como dices es el camino a seguir en este caso. Sin embargo, establecer el valor específicamente todavía significa que mi objeto "Modelo" nunca contiene los valores actualizados. Entonces, si me refiero a él en otro evento (digamos después de que este se haya disparado), @ Model.Str en realidad no contiene el nuevo valor. Para que eso ocurra, ¿debo enviarlo? Gracias por tu respuesta hasta el momento. Responde a mi pregunta inicial. – Jason

+0

Si desea obtener el último valor de sus entradas, querrá obtenerlas de la entrada en sí, puede obtener esto con jQuery $ (# Str) .val(). De lo contrario, si está utilizando Model.Str en otro lugar en su código de JavaScript, ese valor de Model.Str se establece cuando la página se carga por primera vez y nunca se actualizará, a menos que realice una actualización de página completa. – ajrawson

Cuestiones relacionadas