Por favor, haz un clic sobre los anuncios cuando pases por mi blog, ya? =)

Zend Framework 10: Trabajando con Ajax

9 comentarios
Esta es la décima parte de mi tutorial de Zend Framework. La parte anterior la puedes encontrar acá.

Hasta ahora hemos aprendido los conceptos básicos para crear un sistema usando ZF. Sin embargo,  el sistema creado funciona a la manera 'antigua'. Cada vez que hacemos clic en algún enlace, se refresca la página entera. ¿Qué hay de Ajax?

Ajax es una tecnología que permite hacer llamadas al servidor desde javascript, y recibir datos de regreso los que pueden ser mostrados en una capa, tabla o cualquier elemento de la página sin tener que refrescar la página entera. Ahora explicaremos cómo usar Ajax junto con ZF. Verán que es bastante sencillo.

Para nuestro ejemplo usaremos la librería para javascript JQuery. JQuery simplifica la manipulación de los elementos de la página y además permite hacer atractivos efectos visuales con poquísimas líneas de código. Si no sabes o no quieres aprender JQuery, este tutorial de todas formas te servirá.

Si por otra parte te interesa JQuery, acá hay un buen manual:  http://www.desarrolloweb.com/manuales/manual-jquery.html

Instalando JQuery en nuestro proyecto

Seguiremos con nuestro proyecto anterior. Para instalar JQuery basta bajarnos la ultima version,  descomprimirla en una carpeta y enlazar el archivo .js. Puedes bajarte la última versión desde aqu.
Descomprime el archivo, y copia el contenido en la carpeta
/public/javascript/jquery

Debiera quedarte algo así:





Ahora, en nuestro archivo
/applications/layouts/scripts/layout.phtml
agregaremos el enlace al archivo. Coloca esta línea antes del </head>

<script type="text/javascript" src="<?php echo $this->baseUrl(); ?>/javascript/jquery/jquery-1.4.2.min.js"></script>


Ahora, pasaremos a crear las acciones en ZF que se llamarán con Ajax

Creando las acciones


Hasta ahora,  cada vez que invocamos a una accion, a saber, http://localhost/miproyecto/public/index/index, internamente llamamos al controlador Index, a su función indexAction(), la que nos coloca el html en index.phtml. Luego, Se agrega index.phtml dentro de layout.phtml, y se nos devuelve la página creada. Para usar ajax debemos decirle a la acción que no debe usar plantillas .phtml para renderizar el contenido.

En nuestro controlador Index, crearemos una nueva acción (Alt-z create action)
create action saludoajax index

Creando la llamada desde javascript

en saludoajax.phtml pondremos:

<a id="saludolink" href="#">Saludar a</a><span id="saludospan"></span>

<script type="text/javascript">

    //version onClic de jquery para el elemento de id=saludolink
    $('#saludolink').click(function(event)
    {

        //con esto evitamos que el enlace vaya a la direccion indicada
        event.preventDefault();

        var ajaxurl= "<?php echo $this->url(array('controller' => 'index',
    'action' => 'saludoajax2')); ?>";

            //LLAMADA AJAX(). llama a la url guardada en ajaxurl, y lo que devuelva lo coloca
            //en el elemento id= saludospan
            $("#saludospan").load(ajaxurl, function ()
            {
               //function() se llama despues de que se ha hecho la llamada a ajax
               //y el servidor ha devuelto datos
               alert("datos recibidos desde servidor");
            });
        });
</script>

Este código es sencillo, y si no sabes usar JQuery, acá te lo explico. Tenemos dos elementos: un enlace con id= saludolink, y una etiqueta span con id=saludospan

Cuando hagamos clic en el enlace, se hará una llamada ajax al servidor, a la url indicada en la variable ajaxurl, es decir, a la acción saludoajax2Action() del controlador Index, que es la que creamos recién.

esto es solo la llamada desde javascript. Se puede hacer sin JQuery si se desea. La parte importante la veremos ahora, en el servidor.


Creando la respuesta desde el servidor

Primero, crearemos la acción que devuelve la respuesta ajax:
create action saludoajax2 index

Ahora, en el código debemos decirle a la acción que no queremos que devuelva una página web, esto lo hacemos con estas instrucciones:
//indica que esta accion no usará layout.phtml como plantilla del sistema
$this->_helper->layout->disableLayout();
//indica que la accion no usará saludoajax2.phtml
$this->_helper->viewRenderer->setNoRender();

Simple, ¿verdad? Ahora, solo tenemos que devolver los datos haciendo echo();

El código completo de saludoajax2 Action() es:

Archivo /application/controllers/IndexController.php

public function saludoajax2Action()
{
    //esta accion no usara layout.phtml
    $this->_helper->layout->disableLayout();
    //esta accion no renderizara su contenido en saludoajax2.phtml
    $this->_helper->viewRenderer->setNoRender();
   
    //esta es la respuesta a la llamada ajax
    echo "saludos desde el servidor";
}

Ahora, probémoslo. Apunta tu navegador a
http://localhost/miproyecto/public/index/saludoajax


Y haz clic en el enlace "Saludar a", y verás la magia:



Así de simple.

Ahora veremos un ejemplo más complejo. Motraremos un listado de álbumes desde la base de datos usando una llamada Ajax.

Datos con ajax desde la base de datos

Lo que haremos será esto: en el servidor haremos una consulta a la base de datos por todos los álbumes. Guardaremos la respuesta en un array con formato JSON y lo enviaremos al cliente. En javascript, recibiremos ese arreglo y lo mostraremos.


Crearemos la accion listadoajax en el controlador de los albumes:
create action listadoajax album

y le pondremos este código:

public function listadoajaxAction()
{
 // action body
 $this->_helper->layout->disableLayout();
 $this->_helper->viewRenderer->setNoRender();

 $tabla = new Application_Model_DbTable_Album();
 $rows = $tabla->listar()->toArray();
 //funcion de zend framewrok que me codifica el listado para formato Json
 $json = Zend_Json::encode($rows);
 echo $json;
}

Para que veamos como va quedando, apuntemos en navegador a:
http://localhost/miproyecto/public/album/listadoajax

y veremos el listado en formato JSON. Ahora solo nos queda mostrarlo desde javascript.

Agregaremos el código necesario en saludoajax.phtml:

 <a id="saludolink" href="#">Saludar a</a><span id="saludospan"></span>
<!--al presionar este boton, se mostraran ,los albumes-->
<input type="button"  id="veralbumes" value="Ver albumes usando ajax" />
<div id="albumesdiv">

</div>

<script type="text/javascript">

    //version onClic de jquery para el elemento de id=saludolink
    $('#saludolink').click(function(event)
    {

        //con esto evitamos que el enlace vaya a la direccion indicada
        event.preventDefault();

        var ajaxurl= "<?php echo $this->url(array('controller' => 'index',
    'action' => 'saludoajax2')); ?>";

            //LLAMADA AJAX(). llama a la url guardada en ajaxurl, y lo que devuelva lo coloca
            //en el elemento id= saludospan
            $("#saludospan").load(ajaxurl, function ()
            {
                //function() se llama despues de que se ha hecho la llamada a ajax
                //y el servidor ha devuelto datos
                alert("datos recibidos desde servidor");
            });
        });

        //cuando hago clic en el boton id=veralbumes
        $('#veralbumes').click(function(event){

            event.preventDefault();

            var url = "<?php echo $this->url(array('controller' => 'album',
    'action' => 'listadoajax')); ?>";

            var datos = "";
            //funcion que hace llamada a ajax esperando un
            // arreglo json de respuesta
            $.getJSON(url,  function(data)
            {
                //por cada elemento
                //(recordar que recibimos un arreglo de arreglos)
                $.each(data, function(i,row){
                    //guardo sus datos en un texto
                    var fila = i + ')' + row.id + " - " + row.artista_id + " - " + row.nombre + " - " + row.fecha;

                    datos += fila + '<br/>';
                });
                //coloco resultado en capa id=albumesdiv
                $('#albumesdiv').html(datos);
            });
        });

</script>

El código se explica en los comentarios. De forma breve, lo que hacemos acá es crear un botón que ap ser presionado, hará la llamada ajax al servidor. Usaremos una función especial de JQuery para hacer llamadas ajax que devuelven datos en formato JSON, lo que nos libera de tener que decodificarlo nosotros, $.getJSON(). Luego recorremos el arreglo y guardamos sus elementos en la variable 'datos'. Al final, asignamos a la capa id=Albumesdiv el contenido de esa variable.

Probemos, apuntemos de nuevo el navegador a

http://localhost/miproyecto/public/index/saludoajax



Y presionemos el botón. el resultado es:


Como podemos ver, incluir ajax en un sistema hecho con ZF es bastante simple. Solo basta con colocar en la acción que no vamos a usar ninguna plantilla .phtml para mostrar contenido, y devolver con echo() los datos. La url también puede contener parámetros. Incluso podemos (obviamente, por lo demás) enviar formularios usando ajax.


Bien, con esta décima parte ya hemos cubierto todo lo que yo creo que son los conocimientos básicos para usar ZF como dios manda. Sin embargo, quedan algunas dudas:

  • ¿Cómo hago consultas que involucren a más de una tabla? En el caso de los álbumes, en vez de mostrar el id del artista,  me gustaría mostrar el nombre. ¿Cómo puedo hacer eso?
  • ¿Cómo maneja ZF las sesiones?
  • ¿qué hay de los usuarios y sus privilegios?
  • ¿Hay algunos pequeños detalles extra que sería bueno saber?

Las respuestas en el próximo artículo de esta saga.

9 comentarios :

Anónimo dijo...

Muy bien explicados todos tus post sobre el zend framework, felicitaciones.

Ojala el que venga no sea el último ))

Carlos J dijo...

Definitivamente excelente!

Ahora si que me he quedado pegado al Zend Framework. Espero que sigas con los siguientes post sobre las consultas multitabla y sesiones.
Gracias miles.

nicolas dijo...

Hola! estuve leyendo tus tutoriales y son muy buenos!!
me interesaria leer algo sobre sesiones y permisos.. si no me equivoco es zend_auth y zend_acl.
muchisimas gracias!!

Anónimo dijo...

Muy bueno tu articulo, ha pesar de que comento algo tarde espero ayudar a alguien en el tema de respuestas ajax con Zend framework.

Zend framework incorpora un helper especial que nos permite manejar de manera automatica el tipo de respuesta dependiendo de la solicitud http ver (AjaxContentswitcher) en la documentacion de Zend.

David Sonike dijo...

Excelente comentario me ha sido de gran ayuda, en la oscuridad de empezar a utilizar Zend Framewors.

Cristian Reyes dijo...

tengo un problema con la linea 49-50 no me deja hacer el salto de linea al mostralo por el navegaro .... !!!

:(

beco dijo...

excelente tutorial..!!

Wilfo dijo...

Excelente tutorial pero la parte en que cargas de la base de datos con ajax no me funciona.Me podrias enviar el ejemplo a mi correo porfis.
logica_Razon@hotmail.com

Angelorum dijo...

En el ultimo articulo, http://angelorum.blogspot.com/2010/11/zend-framework-12-la-importancia-de.html, hay un enlace para descargar el proyecto.

Saludos