viernes, 26 de junio de 2009

ASP.NET MVC y Ajax: fácil no… facilísimo :)

Hola a todos amigos! ;-)

El comentario de Gabriel en este post de mi blog (http://geeks.ms/blogs/etomas/archive/2009/04/02/asp-net-mvc-controles-chart-y-ajax.aspx) me ha motivado a escribir la siguiente entrada.

Él preguntaba sobre si los controles Ajax de ASP.NET, como p.ej. UpdatePanel se podían usar bajo el framework MVC. No conozco mucho los controles de la Ajax Library porque personalmente no me interesan demasiado, aunque apuesto que la mayoría usan viewstate así que me imagino que no deben poder usarse bajo MVC…

… por otro lado sobreentiendo que la duda de Gabriel, va un poco más allá y quiere saber como usar Ajax con el framework MVC. Pues para verlo muy someramente aquí va esta entrada.

El soporte para Ajax del framework MVC no es que sea espectacular: las vistas tienen una propiedad Ajax que permite acceder al objeto AjaxHelper, que contiene varios métodos para permitir usar Ajax en el framework MVC. P.ej. si quieres poner un link que al pulsarlo cargue el div cuyo id sea "ajaxpanel” puedes hacer:

<%=Ajax.ActionLink("Pulsa aquí", "view1", new AjaxOptions() 
{ UpdateTargetId="ajaxpanel"}) %>



Al pulsar sobre el enlace, el framework MVC ejecutará la acción “view1” (del controlador actual) y la vista que esta acción devuelva será incrustada dentro del elemento DOM cuyo id sea ajaxpanel.



No está mal, pero tiene dos pegas:




  1. De serie no nos viene nada más: si queremos usar imágenes que sean enlaces Ajax, o botones, o una combo, debemos hacerlo nosotros.


  2. Usa la librería propia de Ajax de MS (MicrosoftAjax.js y MicrosoftMvcAjax.js)… No tengo nada personal en contra de esta librería, pero no veo muy claro a que viene: ¿teniendo jQuery, para que reinventar la rueda?



Yo personalmente uso sólo jQuery para mi soporte Ajax… ¿Por qué? Pues porqué me da todo lo que necesito… y más. Además de que es cross-browser y no sólo ofrece temas para Ajax, sino para muchas otras cosas. Si estás desarrollando web y no usas jQuery cuando empieces te preguntarás como has podido estar sin ella todo este tiempo.



Usar jQuery implica que no usamos las funciones del AjaxHelper, pero bueno no importa demasiado: rehacerlas usando jQuery no cuesta nada… ah! Y además jQuery ya viene con el framework MVC (en la carpeta /scripts).



En esta demo, veremos como hacer en un momento una vista con dos botones: al pulsar cada uno de ellos se cargará via Ajax una vista y se incrustará dentro de un div.



1. Inicio: Modificación de la vista master



Creamos una nueva aplicación ASP.NET MVC. Ello nos creará la aplicación inicial, con varias vistas (login, home, registro) para empezar a trabajar. Vamos a modificar directamente la vista inicial (Views/Home/Index.aspx).



Lo primero a hacer es incluir la carga de jQuery en nuestra vista. En mi caso modifico la vista master, para que jQuery esté incluida “de serie” en todas mis vistas… yo la uso a mansalva, y creedme: vais a terminar haciendo lo mismo :)



La vista master está en Views/Shared/Site.Master. Si la abrís vereis que tiene un poco de código. Podeis obviarlo, simplemente añadid una etiqueta <script> dentro del <head>:



<head runat="server">
<
title><asp:ContentPlaceHolder ID="TitleContent" runat="server" />
</
title>
<
link href="../../Content/Site.css"
rel="stylesheet" type="text/css" />
<%-- Incluimos jQuery --%>
<script type="text/javascript" src="../../Scripts/jquery-1.3.2.js">
</
script>

</
head>



(En este caso incluyo jquery-1.3.2.js que es la versión que viene junto con el framework MVC).



2. Modificación de la vista inicial



Como comenté en el punto anterior vamos a trabajar modificando directamente la vista inicial (Views/Home/Index.aspx). Para ello vamos a añadir simplemente dos botones y un <div> vacío que será nuestro contenedor ajax:



<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent"
runat="server">
Home Page
</asp:Content>
<
asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<h2>Pulsa los botones para refrescar el div usando ajax</h2>
<
input type="button" id="view1" value="Vista 1" />
<
input type="button" id="view2" value="Vista 2"/>
<%-- Este es el div que vamos a modificar via ajax --%>
<div id="ajaxpanel" style="border-color:red; border-style:solid;
border-width:thin"></div>
</
asp:Content>



He puesto un border rojo al div para que vea (sí, reconozco que el diseño no es mi fuerte :p).



2.1 Crear las llamadas Ajax al pulsar los botones



Ahora vamos a añadir código javascript para que cuando se pulsen los botones se hagan las llamadas ajax… Si ya estás corriendo a meter un onClick en cada <input> tranquilo: bienvenido al mundo de jQuery :)



Este es el código javascript que puedes colocar en tu página (justo antes del tag <h2>, dentro del asp:Content IndexContent):



<script type="text/javascript">
$(document).ready(function() {
$("#view1").click(function() {
$("#ajaxpanel").load("<%=Url.Action("View1") %>");
});
$("#view2").click(function() {
$("#ajaxpanel").load("<%= Url.Action("View2") %>");
});
});
</script>



Vamos a comentar rápidamente este código… aunque es muy simple muestra dos conceptos clave de jQuery: los selectores y la potencia de sus funciones incorporadas.



El $ es el simbolo “jQuery” por excelencia. $(document) me devuelve un manejador al documento actual. La función ready() espera como parámetro otra función que se ejecutará cuando el documento esté cargado y todos los objetos DOM existan.



En mi caso le paso a la función ready una función anónima que hace lo que a mi me interesa que se haga cuando el documento esté cargado: crear funciones gestoras de los click de los botones para que se llame via Ajax a otras URLs.



El código $("#view1") es un selector: los selectores son una de las claves de jQuery, ya que permiten obtener un manejador jQuery a uno o varios objetos DOM para realizar tareas con ellos. Aquí estoy usando uno de los más simples, el # que devuelve un manejador al objeto DOM cuyo ID sea la cadena que hay después de #. Así $(“#view1”) me devuelve un manejador al objeto DOM cuyo id sea “view1”, que en mi caso es el primer boton.



Una vez tengo un manejador de jQuery puedo hacer barbaridad de cosas con él (que afectarán al objeto (u objetos) DOM a los que apunte dicho manejador). En mi caso llamo a la función click que espera como parámetro otra función. La función click lo que hace es ejecutar la función que se pase como parámetro cuando se lance el evento click del elemento DOM subyacente… Y que le paso como parámetro a la función click? Pues otra función anónima con el código a ejecutar cuando se lance el evento. ¿Y qué codigo es este? Pues usar un selector para obtener un manejador al objeto cuyo ID sea “ajaxpanel” (que es el <div>) y llamar el método load. El método load usa Ajax para cargar la URL especificada y incrustar el resultado dentro del DOM del manejador usado. Es decir, en nuestro caso dentro del div.



Ya casi estamos…



3. Crear las acciones en el controlador



En ASP.NET MVC las URLs se mapean a acciones de los controladores, no a archivos físicos .aspx. Si os fijais en el codigo de la vista se ha usado <%= Url.Action(“xxx”) %> para pasar la URL al método load de jQuery. Esta llamada a URL.Action obtiene la URL de la acción indicada del controlador actual. En mi caso he llamado a las acciones “View1” y “View2”.



Dado que estamos en una vista gestionada por el controlador Home, debemos crear las acciones en el controlador HomeController. La forma más simple de crear una acción es definir un método público en dicho controlador. Así, pues definimos los métodos View1 y View2 en HomeController (que está dentro de la carpeta Controllers):



public ActionResult View1()
{
return PartialView("View1");
}
public ActionResult View2()
{
return PartialView("View2");
}



En este caso las dos acciones son bastante tontas: el controlador no hace nada salvo retornar dos vistas, llamadas View1 y View2. El método PartialView se usa cuando lo que se va a devolver es una vista parcial, esto es una vista que no es un HTML completo sino una parte.



Solo nos queda una pequeña cosa… crear las dos vistas!



4. Crear las dos vistas parciales



Vamos a crear las dos vistas que necesitamos. Dado que estamos creando vistas del controlador Home, debemos crearlas dentro de Views/Home. Para ello hacemos click con el botón derecho en la carpeta Home en el Solution Explorer y seleccionamos la opción Add->View. Esto nos despliega el cuadro de nueva vista de ASP.NET MVC.



image



Damos nombre a la vista (View1) y marcamos la checkbox de “Create a partial view”. Con ello nos va a crear un archivo .ascx, en lugar de un .aspx (que sería una página completa).



Yo he añadido el siguiente código a mi vista View1:



<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<h1>Esta es la vista1</h1>



Ya veis… poca cosa, no?



Repetid el proceso para crear la View2 y… ya habeis terminado.



Ejecutad el proyecto y os aparecerá la página principal, con los dos botones. Pulsad uno u otro y observad como el div se rellena via Ajax con el código de cada vista.



En la última imagen os dejo una captura con el firebug donde se ve la última petición ajax:



image



Esto ha sido una muy breve introducción… pero espero que os haya servido para que os entre el gusanillo de ASP.NET MVC!!! ;-)



Saludos!



pd: Sí… és otro crosspost desde mi blog en geeks.ms

No hay comentarios: