Wa Ajaxservice PDF
Wa Ajaxservice PDF
Wa Ajaxservice PDF
En este artculo, conozca un sistema para hacer y responder a las llamadas de servicio de Asynchronous JavaScript and XML (Ajax) de una manera coherente, basada en eventos. El sistema puede determinar si una llamada de proceso remoto tiene xito o fracasa. Descubra cmo estandarizar el formato del resultado de los objetos retornados por las llamadas de servicio Ajax, proporcionar respuestas basadas en eventos a las llamadas de Ajax y centralizar el manejo de los resultados de Ajax. El sistema utiliza tecnologas PHP, jQuery y JSON, y un cdigo de ejemplo lo gua a travs de la construccin del sistema. El artculo finaliza con un ejemplo de llamada Ajax que muestra cmo interactan las piezas del sistema.
Introduccin
En este artculo, conozca un sistema para hacer y responder a las llamadas de servicio Ajax de una manera coherente, basada en eventos utilizando PHP, jQuery y JSON. El sistema se destina a llamadas de Ajax para servicios como inicio de sesin y actualizacin de perfil (no para la simple carga de contenido, como una pgina HTML). Usted puede utilizar este sistema para determinar si una llamada de proceso remoto tiene xito o fracasa. Acrnimos de uso frecuente
Ajax: Asynchronous JavaScript + XML DOM: Document Object Model HTML: Hypertext Markup Language JSON: JavaScript Serialized Object Notation Marcas Pagina 1 de 13
Copyright IBM Corporation 2012 Realiza llamadas de servicio Ajax con PHP, jQuery y JSON
developerWorks
ibm.com/developerWorks/ssa/
PHP: Hypertext Preprocessor
Para seguir con este artculo se supone que usted: Est familiarizado con la base de la programacin orientada a objetos en JavaScript y PHP. Est familiarizado con el modelo de eventos DOM Level 2 y en cmo interactuar con ella en JavaScript. Para el sistema de ejemplo, usted interacta con este modelo utilizando la librera jQuery. Tiene un conocimiento bsico de los conceptos de Ajax. Sabe cmo los objetos se construyen y son referidos utilizando la notacin JSON. Consulte Resources para informacin adicional sobre estas tecnologas y conceptos. Tecnologas subyacentes El sistema descrito en este artculo utiliza las siguientes tecnologas: Acceso a un servidor PHP 5 con una funcin json_encode de PHP (requiere PHP 5.2.0 o mayor y PHP Extension Community Library o PECL, JSON 1.2.0 o mayor). La biblioteca jQuery JavaScript (Versin 1.4.4 o mayor).
Estandarizar el formato del resultado de los objetos retornados por las llamadas de Ajax.
La clase PHP ServiceResult estandariza el objeto resultante creado al hacer una llamada de Ajax. Todas las llamadas de servicio Ajax retornan un objeto codificado
Realiza llamadas de servicio Ajax con PHP, jQuery y JSON Pagina 2 de 13
ibm.com/developerWorks/ssa/
developerWorks
en JSON de este tipo, dando a todas las llamadas de servicio Ajax una interfaz coherente y predecible. El Listado 1 muestra la clase PHP ServiceResult . Listado 1. Clase PHP ServiceResult .
<?php class ServiceResult { /** * * @var Boolean */ public $success; /** * * @var Array */ public $errors; /** * * @var Array */ public $messages; /** * Holds data returned by a service or passthrough data. */ public $data; /** * * @var String - Event name triggered in JavaScript when service call successful. */ public $onSuccessEvent; /** * * @var String - Event name triggered in JavaScript when service call fails. */ public $onErrorEvent; } ?>
En la parte superior de la clase, el listado define: La propiedad success , que indica si el proceso que se invoca tiene xito o fracasa. Esto no es una indicacin de si la llamada de Ajax en s tiene xito. Si la llamada de Ajax falla, no obtendr el objeto JSON por lo que an necesita manejar las fallas de Ajax con un manejador de fallas de algn tipo. En el ejemplo, xito indica si el usuario es encontrado durante el proceso de inicio de sesin, o si el perfil del usuario se actualiza correctamente. El array errors , que contiene toda la informacin acerca de por qu la llamada no tiene xito. Por ejemplo, si un proceso de inicio de sesin falla, puede contener un mensaje como "No user with that user name and password failed." Al permitir que el objeto ServiceResult pase de nuevo mensajes de error, usted no tiene que modificar el cdigo de los mensajes en su cdigo JavaScript. El cdigo JavaScript simplemente necesita saber que los mensajes de error destinados al usuario estn contenidos en este array. La propiedad messages , que tambin es un array, vuelve a pasar mensajes sin error relacionados al manejador de resultados. Los mensajes pueden ser lo que
Realiza llamadas de servicio Ajax con PHP, jQuery y JSON Pagina 3 de 13
developerWorks
ibm.com/developerWorks/ssa/
usted quiera que el usuario sepa relacionado a la llamada de servicio. Usted puede incluir mensajes de xito, como "You have been logged in." Al mantener separados errores y mensajes genricos, usted no tiene que determinar si un mensaje se relaciona con un error o si es meramente informativo cuando el manejador de resultados se lo muestra al usuario (as se simplifica la lgica en el lado del cliente). La propiedad data que proporciona un mtodo de pasar datos arbitrarios de vuelta al manejador de resultados. Por ejemplo, si est llamando a un servicio de inicio de sesin, data puede contener datos de perfil de usuario. Mientras la propiedad data en s es genrica, los manejadores de resultados para la solicitud especfica deben hacer suposiciones acerca de los datos contenidos en esta propiedad basndose en la llamada de servicio realizada. En cualquier caso, la propiedad data permite a todos los manejadores de resultados saber dnde buscar esos datos. Las propiedades onSuccessEvent y onErrorEvent son cadenas de caracteres para definir el evento a ser transmitido para una llamada de servicio exitosa o fallida. Otra vez, esto se refiere al proceso y no a la llamada de Ajax en s. Ejemplos de dichos eventos son userLoggedIn para xito o loginFailed para falla.
Pagina 4 de 13
ibm.com/developerWorks/ssa/
developerWorks
En el Listado 2: Las funciones addListener y removeListener permiten que usted aada y elimine oyentes desde el objeto de distribucin. El parmetro eventName es el evento al que se est suscrito. El parmetro listener es la funcin a ser registrada. La funcin dispatch transmite el evento especificado en el parmetro eventName . El parmetro data proporciona un mtodo de hacer pasar datos para cualquier funcin de oyente suscrita. La propiedad dispatcher se configura para un objeto jQuery que hace referencia al objeto DOM de documento. Al configurar la propiedad dispatcher para un objeto jQuery haciendo referencia al objeto DOM de documento, todos los eventos de objeto son registrados y transmitidos por el objeto DOM de documento que existe en una pgina dada. Esto es simplemente una propiedad del objeto EventDispatcher , y todos los mtodos hacen referencia a esa propiedad de distribucin. Usted puede cambiar la distribucin subyacente al cambiar esa propiedad. Usted puede utilizar cualquier objeto que proporcione acceso al modelo de eventos DOM Level 2 por el simple cambio de los mtodos de distribucin y actualizacin para corresponder a esa interfaz de distribucin (sin interrumpir cualquiera de los objetos que se heredan del objeto EventDispatcher ). Es clave que todos los objetos se suscriban al mismo distribuidor. El paso siguiente es permitir scripts individuales para heredar las funciones definidas por el objeto EventDispatcher . La empresa en este escenario tiene una convencin para que cada pgina en el sitio tenga un nico objeto controlador responsable por la funcin de esa pgina. Para cerrar la brecha entre estos controladores individuales de pgina y el objeto EventDispatcher , cree una clase BaseController que herede desde el objeto EventDispatcher .
Pagina 5 de 13
developerWorks
ibm.com/developerWorks/ssa/
Por brevedad, las funciones no especficamente relacionadas a la distribucin de eventos se omiten de la muestra de cdigo. Existen otras cosas que los controladores heredan de esta clase. El Listado 3 muestra la clase BaseController . Listado 3. Clase BaseController
function BaseController() { } BaseController.prototype = new EventDispatcher();
Debido a que la propiedad de prototipo BaseController se configura para un objeto EventDispatcher , cualquier controlador especfico de pgina que se hereda de BaseController incluye funciones de distribuidor de eventos.
El manejador se registra contra el objeto del documento porque usted sabe que todas las pginas tienen este objeto. Cada vez que se invoca la funcin, se pasa: Un objeto event de jQuery Ajax (el parmetro evento). El XMLHttpRequest (el parmetro request ). Un objeto representando las configuraciones utilizadas para hacer la llamada de Ajax original (el parmetro settings ). Para el sistema de ejemplo, usted solo est interesado en el objeto XMLHttpRequest y el objeto settings . Observe ms de cerca el cdigo dentro del manejador en el Listado 4. El manejador verifica primero el objeto settings para ver si el formato del resultado est
Realiza llamadas de servicio Ajax con PHP, jQuery y JSON Pagina 6 de 13
ibm.com/developerWorks/ssa/
developerWorks
configurado para JSON. (Recuerde que el propsito de este sistema no es responder a solicitudes simples de carga de contenidos, sino que responder a llamadas de Ajax basadas en servicio, que retorna, codificado en JSON, un ServiceResult ). Si el tipo de datos retornados por la solicitud de Ajax no es JSON, usted no est interesado en responderla y el manejador omite todo el cdigo restante. Si el tipo de datos es JSON, el cdigo crea una instancia JavaScript de EventDispatcher. Debido a que todas las instancias de la clase EventDispatcher hacen referencia a la misma instancia de distribuidor, los eventos transmitidos por ella desencadenan todos los oyentes registrados en ella por cualquier objeto JavaScript que extiende la clase EventDispatcher . El cdigo entonces toma una referencia codificada en JSON de la propiedad responseText del objeto de la solicitud (usando la funcin de jQuery parseJSON ), y la almacena en la variable result . Suponiendo que el anlisis de responseText se realiza correctamente, el manejador comprueba si el objeto result indica que el procedimiento es exitoso comprobando la propiedad success . Si se realiza correctamente, el manejador comprueba si existe definido un onSuccessEvent . Si existe, la instancia de distribuidor event retransmite ese evento junto con el objeto result . Si el objeto de resultado no indica que el proceso es exitoso, el cdigo comprueba si existe un onErrorEvent. Si est definido, la instancia dispatcher retransmite el evento, pasando de nuevo por el objeto result . Mediante las funciones ajaxComplete de jQuery, usted ahora puede notificar a su cdigo del lado del cliente para reaccionar basado en eventos. Los objetos del lado del cliente no tienen que registrarse como oyentes en la llamada de Ajax. El cdigo del lado del cliente no tiene siquiera que saber que se est realizando una llamada de servicio. Simplemente tiene que saber qu eventos escuchar y cmo responder a los datos que pasan de nuevo por l.
Pagina 7 de 13
ibm.com/developerWorks/ssa/
<?php $ctrl = new LoginController(); $result = new ServiceResult(); $result->success = $ctrl->login($_POST['username'], $_POST['password']); $result->errors = $ctrl->errors; $result->onSuccessEvent = 'refreshPage'; $result->onErrorEvent = 'userLoginFailed'; echo json_encode($result); ?>
Es necesario un objeto JavaScript que invoque el servicio. Para este ejemplo, se supone que usted ya cre un formulario HTML de inicio de sesin. Llame el objeto responsable por hacer la llamada de servicio LoginController, como en el Listado 6. Llamada de servicio Listado 6. LoginController
LoginController.prototype.login = function() { var self = this; var username = jQuery('#loginForm .email').val() var password = jQuery('#loginForm .password').val() var data = { username:username, password:password, }; jQuery.ajax({ url:'login.php', async:true, service:'login', type:'post', dataType:'json', data:data }); function LoginController() { var self = this; jQuery(document).ready(function() { self.onLoad(); }) } LoginController.prototype = new BaseController(); LoginController.prototype.onLoad = function() { var self = this; this.addListener('userLoginFailed', function(event, result) { self.onLoginFailed(result); }) } LoginController.prototype.onLoginFailed = function(result) { jQuery('#errorDisplay').html(result.errors[0]); } }
Debido a que este sistema responde a las llamadas de servicio Ajax mediante eventos, usted no pasa manejadores de resultados y fallas a la llamada jQuery.ajax . Ahora que ha invocado el servicio, usted desea permitir a los objetos responder a onSucessEvents y onErrorEvents definidos el el objeto ServiceResult que
Realiza llamadas de servicio Ajax con PHP, jQuery y JSON Pagina 8 de 13
ibm.com/developerWorks/ssa/
developerWorks
es retornado por el servicio de inicio de sesin. Es necesario que los objetos que responden hereden desde EventDispatcher, que es heredable extendiendo BaseController. En este caso, el objeto LoginController muestra al usuario un mensaje explicando que el intento de inicio de sesin ha fallado. Si el inicio de sesin tiene xito, el objeto AppController responde actualizando la pgina. Empiece con el LoginController, como en el Listado 7. Aadiendo oyentes de Listado 7. LoginController
function LoginController() { var self = this; jQuery(document).ready(function() { self.onLoad(); }) } LoginController.prototype = new BaseController(); LoginController.prototype.onLoad = function() { var self = this; this.addListener('userLoginFailed', function(event, result) { self.onLoginFailed(result); }) } LoginController.prototype.onLoginFailed = function(result) { jQuery('#errorDisplay').html(result.errors[0]); }
El constructor invoca una funcin onLoad . Esto no es clave para el ejemplo, pero se incluye porque puede ser necesario que este controlador haga referencia a objetos DOM no disponibles hasta que se cargue la pgina. Dos elementos claves a notar son: El objeto prototipo del LoginController es un BaseController. Por lo tanto, tambin hereda los mtodos de EventDispatcher . Utilice el mtodo EventDispatcher addListener en la funcin onLoad . El evento que se pasa coincide con el onSuccessEvent retornado por el objeto ServiceResult que es retornado por el servicio de inicio de sesin. La funcin de manejador registrada se pasa junto al objeto result , que es el objeto ServiceResult codificado en JSON, retornado por el servicio de inicio de sesin. El mtodo onLoginFailed utiliza el array de error del objeto result para mostrar un mensaje al usuario. El manejo de un inicio de sesin fallido es atendido. Cuando el inicio de sesin del usuario es exitosa, usted desea que la pgina se actualice para que los datos de inicio de sesin del usuario sean actualizados. Sin embargo, hay otras ocasiones en que puede querer responder a llamadas de servicio al actualizar la pgina, por ejemplo, cuando los usuarios actualicen sus perfiles. En vez de tener varios controladores con manejadores de resultados que actualizan la pgina, mantenga esta funcin en un controlador de nivel superior.
Realiza llamadas de servicio Ajax con PHP, jQuery y JSON Pagina 9 de 13
developerWorks
ibm.com/developerWorks/ssa/
Entonces, las llamadas de servicio que quieran actualizar la pgina para actualizar los datos de la sesin pueden hacerlo simplemente distribuyendo el tipo de evento refreshPage como el onSucessEvent. Para hacerlo, repita el proceso que utiliz para el LoginController en el AppController, como en el Listado 8. Objeto Listado 8. AppController
function AppController() { var self = this; jQuery(document).ready(function() { self.onLoad(); }) } AppController.prototype = new BaseController(); AppController.prototype.onLoad = function () { this.addListener('refreshPage', function(event, user) { window.location.reload() }) }
Otra vez, el AppController simplemente configura su prototipo a una instancia de BaseController y registra una funcin de oyente utilizando addListener para el evento refreshPage . Ahora que ha creado los objetos que responden y registrado los oyentes de eventos, incluya el script con la funcin onAjaxComplete de manejador de eventos. Al completarse la llamada de servicio, el manejador onAjaxComplete distribuye el evento apropiado que notifica a la funcin de manejador registrada. No es necesario que el LoginController y el AppController tengan conocimiento uno del otro. Incluso no saben que estn respondiendo a una llamada de servicio --y mucho menos a la misma llamada de servicio.
Resumen
En este artculo se examin un sistema para hacer llamadas de servicio Ajax que: Estandariza el formato del resultado de los objetos retornados por las llamadas de servicio Ajax utilizando un objeto ServiceResult PHP que es retornado en un formato codificado en JSON. Proporciona respuestas basadas en eventos a las llamadas de Ajax diseando un objeto EventDispatcher de JavaScript que permite a todas las subclases registrar y responder a eventos en un distribuidor comn. Centraliza el manejo de los resultados de Ajax mediante un manejador onAjaxComplete de jQuery para actuar como un manejador centralizado que transmite los eventos especificados en el objeto ServiceResult retornado por la llamada de servicio.
Pagina 10 de 13
ibm.com/developerWorks/ssa/
developerWorks
Un ejemplo de llamada Ajax mostr cmo usted puede crear dos objetos JavaScript, que no tienen conocimiento uno de otro, para responder a la misma llamada de servicio.
Pagina 11 de 13
developerWorks
ibm.com/developerWorks/ssa/
Recursos
Aprender Classes and Objects: Lea ms sobre programacin orientada a objetos en el manual de PHP. "Get started with object-oriented JavaScript code" (developerWorks, abril de 2011): Aprenda cmo crear objetos utilizando JavaScript. jQuery Documentation: Aprenda ms sobre la utilizacin de la biblioteca de jQuery. jQuery ajaxComplete function: Obtenga ms detalles acerca de cmo trabaja esta funcin. JavaScript Object Notation: Aprenda ms sobre sintaxis y uso. json_encode: Lea cmo PHP codifica objetos en formato JSON. DOM events: Lea esta entrada de Wikipedia para saber ms acerca de eventos DOM Level 2. developerWorks technical events and webcasts: Mantngase actualizado con la tecnologa en estas sesiones. developerWorks on Twitter: nase hoy para seguir los tweets de developerWorks. developerWorks podcasts: Escuche interesantes entrevistas y discusiones para desarrolladores de software. Demostraciones on demand de developerWorks: Observe demostraciones que van desde la instalacin de productos y configuracin para principiantes hasta funcionalidades avanzadas para desarrolladores experimentados. Obtener los productos y tecnologas jQuery JavaScript library: Descargue la versin 1.4.4 o mayor. IBM product evaluation versions: Descargue o vaya a explore the online trials in the IBM SOA Sandbox y experimente con herramientas de desarrollo de aplicaciones y productos middleware de DB2, Lotus, Rational, Tivoli, y WebSphere. Comentar developerWorks profile: Cree hoy su perfil y vaya a set up a watchlist. XML zone discussion forums: Participe en cualquiera de las diferentes discusiones relacionadas con XML. El developerWorks community: Conctese con otros usuarios developerWorks mientras explora los blogs, foros, grupos y wikis dirigidos a desarrolladores.
Pagina 12 de 13
ibm.com/developerWorks/ssa/
developerWorks
Sobre el autor
Jeremy J. Wischusen Jeremy Wischusen tiene ms de 13 aos de experiencia diseando sitios web y aplicaciones para clientes como Purple Communications, myYearbook.com, HBO y otros, desarrollando sistemas frontend y backend con Flash, Flex, jQuery, PHP, MySQL, MSSQL y PostgreSQL. Ha enseado diseo web, Flash y ActionScript para clientes como Wyeth Pharmaceuticals, The Vanguard Group, Bucks County Community College y The University of the Arts. Copyright IBM Corporation 2012 (www.ibm.com/legal/copytrade.shtml) Marcas (www.ibm.com/developerworks/ssa/ibm/trademarks/)
Pagina 13 de 13