Comunidad de diseño web y desarrollo en internet online

Conección a WebService y delay en la respuesta

Citar            
MensajeEscrito el 19 Feb 2007 04:55 pm
Hola!

No sé si debo colocar este post en este tópico, porque si bien mi consulta tiene que ver con flash y datos, no uso ni remoting ni AMFPHP.
Inclusive estoy seguro que mi duda tiene más que ver con diseño y análisis de software (y aún codificación en AS), que con la plataforma Flash en particular

En fin, el asunto es que estoy usando Flash para hacer una consulta relativamente compleja a un webservice. El objetivo es consultar una base de datos inmobiliaria, por la disponibilidad de cierto tipo de inmueble, en cierta región del mundo, con determinados parámetros como tipo de operación, monto, moneda a pagar, etc.

Como la construcción de la consulta está articulada a través de varias opciones interdependientes, debo realizar varias llamadas a distintas operaciones del webservice, con el objeto de ir actualizando ciertos componentes de Interfaz de Usuario.
Por ejemplo, hay un ComboBox Paises, y otro ComboBox Provincias, y al seleccionar algún País en particular en el primer combo de paises, el segundo combo de provincias debe actualizarse dinamicamente, con el resultado de una consulta al webservice llamando a la operacion Provincias, y pasando como parametro el ID del Pais seleccionado.

Y así con aproximadamente unos 10 combos interdependientes.

Esta es la primera vez que uso un WebService con Flash, y la dificultad inicial con la que me encuentro es cierto delay o demora entre la llamada al webservice y la respuesta correspondiente.

Creé una función getResult que me sirve para obtener el resultado de la consulta al webservice, usando cualquiera del las instancias webServiceConnector que tengo en el escenario. Si el método trigger() no arroja errores debería devolver el valor de la propiedad results del webServiceConnector utilizado. El objetivo es tener libertad de usar el conector que desee, sin tener que atarme a un dataBinding en particular.


Código :

var wscListener:Object = new Object();
wscListener.fault = function (stat) {
   if (stat.code == "WebServiceFault"){
      trace(stat.data.faultcode);
      trace(stat.data.faultstring);
      trace(stat.data.detail);
   }
};
   
wscListener.sendFunction = function (misParametros:Array) { //todavía no sé muy bien qué hacer con esto
}; 

wscListener.res = function (ev) {//todavía no sé muy bien qué hacer con esto
};

function getResult(conector:WebServiceConnector, parametros:Array, operacion:String) {
   conector.params = parametros;
   with(conector) {
      addEventListener("status", wscListener.fault);
      addEventListener("send", wscListener.sendFunction);
      addEventListener("result", wscListener.res);
      operation = operacion;
      trigger();
   }
   return conector.results;
}


Y luego para ver qué tal funcionaba, le asingné la función a un callback de un botón:

Código :

paises_btn.onRelease = function() {
   trace(getResult(_root.paisesConector, ["idUsuario", "cuenta", "password", "otroParametro"], "Paises"));
}


Cuando aprieto el botón por primera vez obtengo en la ventana de salida "undefined", si vuelvo a apretarlo ya obtengo el XML de respuesta del webservice.

No sé cómo manejar ese delay de respuesta para poder asignar el return de getResult() a una funcion tipo xmlACombo() que recorra el xml de respuesta y lo use para poblar el combo apropiado.

Código :

function xmlACombo(fuente:String, destino) {
   destino.dataProvider = [];
   var mi_xml:XML = new XML(fuente);
   var mi_cb = destino;
   for (var i:Number = 0; i < mi_xml.firstChild.childNodes.length; i ++) {
      mi_cb.addItem({data:mi_xml.firstChild.childNodes[i].attributes.ID, label:mi_xml.firstChild.childNodes[i].attributes.Nombre});
   }
}


De esta forma quizás pueda ir asignando eventListeners a los comboBox que llamen a las funciones xmlACombo(getResult(parametros), comboAPoblar)

El tema es que ese actionscript se ejecuta mucho más rápido que el tiempo que demora en llegar el resultado de la consulta al webServiceConnector.

Me doy cuenta que, por ejemplo tengo a las funciones del objeto eventListener, asignado al conector, de adorno, pero no sé cómo pasarles como parámetro los parámetros que a su vez le doy a getResult.
De alguna forma necesito que getResult no devuelva nada hasta que llegue el resultado.

Estoy perdido y agradecería cualquier sugerencia que me pudiesen dar.

Desde ya muchas gracias!

Por matias.quaglia

4 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 19 Feb 2007 08:27 pm
Bueno, vamos avanzando!

Me dije, si el evento result de webServiceConnector se propaga cuando se produce la llamada exitosa al webService, entonces por acá debe ser el asunto.

Si uso ese eventListener para desencadenar tanto la transformación del resultado de la llamada, como la llamada subsiguiente, para el siguiente comboBox relacionado, entonces soluciono el tema del delay...

El gran problema es que a un objeto o función EventListener no le podemos pasar muchos parámetros que digamos, excepto type y target... entonces cómo hago para pasar los parámetros a la función xmlACombo... mhhhh... por contexto!!!

Creo el objeto eventListener para el webServiceConnector:

Código :

var wscListener:Object = new Object();
wscListener.fault = function (stat) {
   if (stat.code == "WebServiceFault"){
      trace(stat.data.faultcode);
      trace(stat.data.faultstring);
      trace(stat.data.detail);
   }
};
   
wscListener.sendFunction = function (ev) {//este sigue de adonro
}; 
/*la idea es que hay varios conectores uno para cada operacion, aunque esto no sea necesario,
permite que el eventListener "se dé cuenta" de qué webServiceConector lo está llamando,
y como resultado setea los parámetros de xmlACombo adecuadamente*/
wscListener.res = function (ev) {
   switch(ev.target._name) {
      case "paisesConector" :
         xmlACombo(ev.target.results, _root.paises_cb);
         break;
      case "provinciasConector" :
         xmlACombo(ev.target.results, _root.provincias_cb);
         break;
      case .............................................

   }
};


Con esta función obtengo el resultado de una consulta al web service

Código :

function getResult(conector:WebServiceConnector, parametros:Array, operacion:String) {
   conector.params = parametros; // lo tuve que poner acá... who knows?
   with(conector) {
      //params = parametros; <--- no me pregunten por qué, pero no funciona así
      addEventListener("status", wscListener.fault);
      addEventListener("send", wscListener.sendFunction);
      addEventListener("result", wscListener.res);
      operation = operacion;
      trigger();
   }
}


Con esta transformo el resultado de la consulta en un dataProvider de un comboBox (los parámetros que determinan a qué combo va a aparar el result quedan seteados en el eventListener result del webServiceConnector)

Código :

function xmlACombo(fuente:String, destino) {
   destino.dataProvider = [];
   var mi_xml:XML = new XML(fuente);
   mi_xml.ignoreWhite = true;
   for (var i:Number = 1; i < mi_xml.childNodes[1].childNodes.length; i ++) {
      if (mi_xml.childNodes[1].childNodes[i].attributes.ID != undefined && mi_xml.childNodes[1].childNodes[i].attributes.Nombre != undefined) {
         destino.addItem({data:mi_xml.childNodes[1].childNodes[i].attributes.ID, label:mi_xml.childNodes[1].childNodes[i].attributes.Nombre});
      }
   }
}


Finalmente, agrego el eventListener a los comboBox (de forma análoga al eventListener de los webSericeConnector, el eventListener determina qué parámetros pasar en función del objeto que propaga el evento:

Código :

var cbListener:Object = new Object();
cbListener.change = function(ev) {
   trace(ev.target._name);
   switch(ev.target._name) {
      case "paises_cb" :
         getResult(_root.provinciasConector, ["parametro", "otroParam", "yOtro", ev.target.selectedItem.data], "Provincias");//acá seteamos dinamicamente un  parámetro en funcion del elemento seleccionado
         break;
      case "provincias_cb" :
         ...............................
      case .................................... :
         ...............................

   }
};


Sé que le falta mucho estilo y elegancia, y hay muchísimo por mejorar, pero esta es la primera etapa de las conocidas tres etapas de un desarrollo


    Make It Work
    Make It Right <---- lo que viene ahora
    Make It Fast


Muchas gracias a todos!

Por matias.quaglia

4 de clabLevel



Genero:Masculino  

firefox

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.