<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>finis coronat opus: Ajax del pino o lo que brilla no es mi culo...</title>
    <link>http://www.finiscoronatopus.com/articles/2005/03/18/ajax-del-pino-o-lo-que-brilla-no-es-mi-culo</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>perpetrando historias desde 2002</description>
    <item>
      <title>Ajax del pino o lo que brilla no es mi culo...</title>
      <description>&lt;p&gt;Jano-r no acaba de ver muy claro el esfuerzo que requiere utilizar ajax asi que ahora que me he convertido por ignominia popular en el Darth Ajax Vader de esta guerra contra la Republica del diseÃ±o perfecto, la mantenibilidad perfecta, la documentacion perfecta, y las pajas perfectas he decido poner un ejemplo claro de lo que es Ajax y como se usa. Cogere el propio caso de Jano:&lt;/p&gt;
&lt;blockquote&gt;un conjunto de combos donde cada uno modifica el valor de los otros. Obtengo todos los datos en xml, y uso xsl para generar html y javascript. Cuando un combo cambia llama por xmlhttprequest al servidor para recuperar otro xml y reescribir la pÃ¡gina. No se cambia de pÃ¡gina durante toda la operaciÃ³n. Es eficiente y simple, pero hay mucho javascript especifico. Hay que documentarlo bien, y el javascript no se presta. Â¿Puede hacerse una libreria OO de JS que lo simplifique? quiza, no lo tengo claro. XSL + JS creo que facilmente desemboca en programaciÃ³n especifica para cada pÃ¡gina que resulta difÃ­cil de mantener. A mi me lo parecÃ­a en su momento. No sÃ© si es buena opciÃ³n para una aplicaciÃ³n entera.&lt;/blockquote&gt;
&lt;p&gt;
Bien como hemos aprendido en la universidad de la vida empezaremos haciendo un pequeÃ±o test:&lt;/p&gt;
&lt;code&gt;
&lt;pre&gt;
function getCombo(value){
     var rs = new JSQuery();
     rs.addParam(1,value);
     // here we could add more param-related bindings
     rs.execute();
     while (rs.next()){
             // add to the destination Combo as 
             // rs.getValue(idx) where idex =1,2,3....
           
     }
}
&lt;/pre&gt;
&lt;/code&gt;
&lt;p&gt;Si lo incrustamos en un html y lo cargamos veremos que nos da un error porque JSQuery no esta definido. Solucionemos eso:&lt;/p&gt;
&lt;code&gt;
&lt;pre&gt;
function JSQuery(query) {
    this.query = query;
    this.counter = 0;
    this.params = new Array();
    this.result = null;
    this.currentRow = null;
    this.endpoint = "/SomeEndPointServiceOfOurWebApp";

    this.executed = false;

    this.addParam = function(idx, param) {
        this.params[idx] = param;
    };

    this.execute = function() {
        var d = new Date();
        // prevent caching generating some pseudo-random string
        var src = this. endpoint  + this.composeParams() + "&amp;watermark=" + d.getTime();
        var xmlHttp = XMLHttp.create();
        // If you want sync/async you must adjust 
        // the 3rd parameter, and in case of async 
        // supply a callback method.
        xmlHttp.open("GET", src, false);    
        xmlHttp.send(null);
        this.initialize();
        this.result = xmlHttp.responseXML;
        this.executed = true;
    };
    this.getValue = function(idx) {
        if (this.executed) {
            return this.currentRow.getElementsByTagName("value" + idx).item(0).childNodes.item(0).nodeValue;
        } else {
              return null;
          }
    };

    this.toString = function() {
        if (this.executed)
                return this.result.xml;
        else
                return null;
    };

    this.composeParams = function() {
        var tex = "";
        for (i = 1; i &lt; this.params.length; i++) {
            tex = tex + "&amp;param" + i + "=" + this.params[i];
        }
        return tex;
    };

    this.next = function () {
        this.counter++;
        this.currentRow = this.result.getElementsByTagName("row" + this.counter).item(0);
        if (this.currentRow != null) {
            return true;
        } else {
              return false;
          }

    };

}
&lt;/pre&gt;
&lt;/code&gt;
Ahora si incrustamos estos dos elementos ya no tendremos errores de script pero nos falta lo principal, los datos a servir. Para esta caso de ejemplo supongamos unos datos como los siguientes:
&lt;pre&gt;
&amp;lt;result&amp;gt;
      &amp;lt;row1&amp;gt;
          &amp;lt;value1&amp;gt;Valor 1 &amp;lt;/value1&amp;gt;
          &amp;lt;value2&amp;gt;Valor 2&amp;lt;/value2&amp;gt;
      &amp;lt;/row1&amp;gt;
&amp;lt;/result&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
Ahorrarse cualquier comentario sobre el formato del xml - YA he dicho que es solo un ejemplo-.  Como es de suponer en una herramienta de producciÃ³n habria que definir un api ( mi preferida es del tipo REST como la de &lt;a href="http://www.flickr.com/services/api/response.rest.html"&gt;Flickr&lt;/a&gt;) en condiciones (incluyendo encodings y seccciones CDATA si fueran necesarias):
&lt;/p&gt;
&lt;pre&gt;
&amp;lt;?xml version="1.0" encoding="utf-8" ?&amp;gt;
&amp;lt;rsp stat="ok"&amp;gt;
    &amp;lt;method&amp;gt;flickr.test.echo&amp;lt;/method&amp;gt;
    &amp;lt;api_key&amp;gt;6df04d92d4d4d0048f53fd6bc8db58a6&amp;lt;/api_key&amp;gt;
&amp;lt;/rsp&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
Resumiendo : 1 clase (JSQuery) provee de la funcionalidad necesaria. Â¿Mucho esfuerzo?. No lo creo. Â¿Javascript especifico?. Umm lo justo para actualizar los widgets que como explicaba hace dos posts tambien se podria refactorizar y ser transparente. Â¿XSL?  . Â¿Para quÃ©?. Â¿Documentarlo bien?.  Aunque no recuerdo ahora nombres seguro que hay mas de un framework que permie escribir js-docs al estilo de las javadocs. Por supuesto esto no es mas que un boceto a bote pronto extractado de como estaba una libreria que mi empresa desarrollo en el 2001 y que ahora contiene algunas funcionalidades como paginacion en el cliente y en el servidor, cacheo de datos, etc... A posteriori se puede refactorizar aislando el trasporte del manejo de resultados (como aparece aqui en el XMLHttp.create()) , generando una clase base para las consultas y adaptandola para diferentes formatos, y desarrollando la idea de los widgets; pero creo que la idea se coge, y sinceramente jano no pienso que sea especialmente inmantenible (para ser exactos y como he defendido desde el principio no mas que las chapuzas que se pueden hacer en el lado del servidor).
&lt;/p&gt;
&lt;p&gt;Para finalizar creo que a la vista esta que es una buena solucion para *algunas* aplicaciones. Personalmente solo he encontrado algun problema de freezings del GUI en el IE debidas a mi estupidez al utilizar llamadas *sincronas* que son las que hay que evitar bajo todos los medios. &lt;/p&gt;

&lt;p&gt;Por lo demas, la familia, bien, como siempre.&lt;/p&gt;</description>
      <pubDate>Fri, 18 Mar 2005 18:39:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:a2b44b5e08b2769240c6f75e14fc1217</guid>
      <author>Aitor Garcia</author>
      <link>http://www.finiscoronatopus.com/articles/2005/03/18/ajax-del-pino-o-lo-que-brilla-no-es-mi-culo</link>
      <category>Java</category>
    </item>
    <item>
      <title>"Ajax del pino o lo que brilla no es mi culo..." by Jano</title>
      <description>&lt;p&gt;jarrrrl no me queda otra que darte la razón, tiene buena pinta :-)&lt;/p&gt;


	&lt;p&gt;el xsl era porque podia escoger una consulta por combo o una consulta tocha que trajera todos los datos del tirón y no consultar más, asi que cargaba el xml y luego usaba xsl para reescribir los combos, que puede resultar bastante rollo, y se aparta un poco del tema. Más fácil cachear el xml y llamar desde cada combo supongo.&lt;/p&gt;</description>
      <pubDate>Mon, 21 Mar 2005 11:02:34 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:757bbb9791f72d0829c13e62cfc611b2</guid>
      <link>http://www.finiscoronatopus.com/articles/2005/03/18/ajax-del-pino-o-lo-que-brilla-no-es-mi-culo#comment-290</link>
    </item>
    <item>
      <title>"Ajax del pino o lo que brilla no es mi culo..." by Roberto Salicio</title>
      <description>&lt;p&gt;Que ilusión ver el JSQuery!! Que tiempos aquellos y mira que funcionaba y funciona bien. Quien nos iba a decir que a esto le pondrian nombre :D&lt;/p&gt;</description>
      <pubDate>Fri, 18 Mar 2005 20:32:48 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:7f102f2159599f4cdb6ef7b8437d7c21</guid>
      <link>http://www.finiscoronatopus.com/articles/2005/03/18/ajax-del-pino-o-lo-que-brilla-no-es-mi-culo#comment-289</link>
    </item>
  </channel>
</rss>
