Ajax del pino o lo que brilla no es mi culo... 2
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:
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.
Bien como hemos aprendido en la universidad de la vida empezaremos haciendo un pequeño test:
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....
}
}
Si lo incrustamos en un html y lo cargamos veremos que nos da un error porque JSQuery no esta definido. Solucionemos eso:
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() + "&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 < this.params.length; i++) {
tex = tex + "¶m" + 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;
}
};
}
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:
<result>
<row1>
<value1>Valor 1 </value1>
<value2>Valor 2</value2>
</row1>
</result>
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 Flickr) en condiciones (incluyendo encodings y seccciones CDATA si fueran necesarias):
<?xml version="1.0" encoding="utf-8" ?>
<rsp stat="ok">
<method>flickr.test.echo</method>
<api_key>6df04d92d4d4d0048f53fd6bc8db58a6</api_key>
</rsp>
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).
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.
Por lo demas, la familia, bien, como siempre.
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
jarrrrl no me queda otra que darte la razón, tiene buena pinta :-)
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.