[SOLUCIONADO]JsonReader no carga los valores del objeto JSON
Hola a todos, y enhorabuena por el foro y el sitio Quizzpot:
Estoy desarrollando una aplicación que necesita cargar unos valores de una web externa (Catastro de España), y que luego un JsonReader se encarga de interpretar.
La web externa devuelve las consultas del callejero en formato XML y luego yo en php las convierto a JSON con una clase de php desarrollada por IBM.
Para que os podais hacer una idea, la llamada que hago mediante el proxy que luego cargo en el Store es:
<!-- m -->http://www.geofoc.com/libphp/proxyCatas ... &tipo=json<!-- m -->
Y la salida resultante para esta consulta es:
{"consulta_callejero":{"control":{"cuca":"26"},"callejero":{"calle":[{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"24","tv":"LA","nv":"RIOJA"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"1","tv":"CL","nv":"ALBERTO MARTIN"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"2","tv":"CL","nv":"CASTILLO"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"3","tv":"CL","nv":"CEMENTERIO"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"4","tv":"CL","nv":"CUEVAS"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"20","tv":"CR","nv":"DOMINGO"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"5","tv":"CL","nv":"ERAS"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"6","tv":"CL","nv":"HOSPITAL"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"7","tv":"CL","nv":"IGLESIA"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"8","tv":"TR","nv":"IGLESIA"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"9","tv":"CL","nv":"JUAN DIOS O\u00d1A"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"22","tv":"DS","nv":"LEIVA"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"999","tv":"CL","nv":"LIMITE CASCO URBANO"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"12","tv":"TR","nv":"MAYOR"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"10","tv":"CL","nv":"MAYOR"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"11","tv":"PZ","nv":"MAYOR"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"25","tv":"CL","nv":"PRESA"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"13","tv":"CL","nv":"RIO"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"23","tv":"AV","nv":"RIOJA LA"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"15","tv":"TR","nv":"S ISIDRO"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"14","tv":"CL","nv":"S ISIDRO"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"16","tv":"CL","nv":"S JUAN"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"17","tv":"CL","nv":"S MIGUEL"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"18","tv":"TR","nv":"S MIGUEL"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"19","tv":"CL","nv":"SANTA ANA"}},{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"21","tv":"CR","nv":"TORMANTOS"}}]}}}Por último el código extjs que me construye un comboBox para poder elegir la calle en concreto es:
this.jsonCallReader = new Ext.data.JsonReader( { totalRecords: 'cuca', root: 'consulta_callejero', //también he probado // root: 'calle' }); this.dsCall = new Ext.data.Store({ proxy: new Ext.data.HttpProxy({ url: './libphp/proxyCatastro.php', method: 'GET', }), reader: this.jsonCallReader, }, [ {name: 'ncalle', mapping: 'consulta_callejero > callejero > calle > dir > nv'}, // si cambio el root del jsonReader a calle, sería //{name: 'ncalle', mapping: 'dir > tv'} ] ); this.comboCall = new Ext.form.ComboBox({ store: this.dsCall, displayField: 'ncalle', valueField: 'ncalle', name: "calle", mode: 'local', editable: true, emptyText: 'Elige una calle..', triggerAction: 'all', listeners: { 'select' : { scope : this, fn: function(cmb, rec, idx) { this.textoDir = cmb.getValue(); //seleccionado } } } });Seguramente será un error de código por mi parte, pero no consigo dar con el problema. Muchas grácias de antemano..
[b]El problema[/b]
A simple vista me he dado cuenta que tienes mal configurado el reader, seguramente el store si esta haciendo la petición Ajax y si esta recibiendo el json del servidor, el problema esta en que no sabe como procesar esa información ya que has configurado incorrectamente el reader <!-- s;) --><!-- s;) -->
Te recomiendo que utilices el JsonStore en lugar del Store, de esta manera escribes menos código <!-- s:D --><!-- s:D -->
[b]Solución[/b]
Lo primero que tienes que hacer es identificar el "root" en la información que estas retornando:
{"consulta_callejero":{ "control":{"cuca":"26"}, "callejero":{ "calle":[{ //<-- ROOT "loine":{"cp":"26","cm":"87"}, "dir":{"cv":"24","tv":"LA","nv":"RIOJA"} },{ "loine":{"cp":"26","cm":"87"}, "dir":{"cv":"1","tv":"CL","nv":"ALBERTO MARTIN"} },{ "loine":{"cp":"26","cm":"87"}, "dir":{"cv":"2","tv":"CL","nv":"CASTILLO"} },{ "loine":{"cp":"26","cm":"87"}, "dir":{"cv":"3","tv":"CL","nv":"CEMENTERIO"} }] } } }Lo que te recomiendo es que solamente le envies al store la información que necesites, osea, procesa mediante PHP la información para que únicamente regrese algo como lo siguiente:
{ "total": 4, //<-- esto es opcional "calle":[{ //<-- ROOT "loine":{"cp":"26","cm":"87"}, "dir":{"cv":"24","tv":"LA","nv":"RIOJA"} },{ "loine":{"cp":"26","cm":"87"}, "dir":{"cv":"1","tv":"CL","nv":"ALBERTO MARTIN"} },{ "loine":{"cp":"26","cm":"87"}, "dir":{"cv":"2","tv":"CL","nv":"CASTILLO"} },{ "loine":{"cp":"26","cm":"87"}, "dir":{"cv":"3","tv":"CL","nv":"CEMENTERIO"} }] }de esta manera no tendras problemas al configurar tu store, que sería de la siguiente manera:
var store = new Ext.data.JsonStore({ url: 'libphp/proxyCatastro.php', root: 'calle', fields: [{name:'cp',mapping:'loine-cp'},{name:'cm',mapping:'loine-cm'}, {name:'nv',mapping:'dir-nv'} ] });Fíjate como he creado las propiedades cambiando su respectivo mapping, prueba con eso a ver como te va y me cuentas. Saludos
Hola:
He probado con el JsonStore y no me devuelve nada.
He vuelto a probar con un Store normal, y me devuelve la respuesta con el JSON de las calles pero luego no me carga el comboBox.
La llamada la realizo desde otro combo, para que lance el aviso de carga desde un listener: 'select' , así:
..........(listener del combo que activa la carga del store)......... 'select' : { scope: this, fn : function(cmb, rec, idx) { this.textoLoc = rec.get('nombre'); this.dsCall.load({ params:{ provincia: this.textoProv, //provincia municipio: this.textoLoc, // municipio consulta: 'callejero', // tipo consulta tipo: 'json' // tipo de respuesta de proxyCatastro.php } }); } }, ...............(fin del listener)..................Y el Store que SÍ funciona sería el siguiente:
this.jsonCallReader = new Ext.data.JsonReader( { totalRecords: 'cuca', root: 'calle', }); this.dsCall = new Ext.data.Store({ proxy: new Ext.data.HttpProxy({ url: './libphp/proxyCatastro.php', method: 'GET', }), reader: this.jsonCallReader, }, [ {name: 'ncalle', mapping: 'dir-nv'}, {name: 'tcalle', mapping: 'dir-tv'} ] ); this.comboCall = new Ext.form.ComboBox({ store: this.dsCall, displayField: 'ncalle', valueField: 'ncalle', name: "calle", mode: 'local', editable: true, emptyText: 'Elige una calle..', triggerAction: 'all', listeners: { 'select' : { scope : this, fn: function(cmb, rec, idx) { this.textoDir = cmb.getValue(); //seleccionado } } } });No se si puede ser el mapeado de los campos 'dir-nv', ya que en algún sítio los he visto de la forma 'dir > nv'. No se que hacer. Gracias por todo.
Seguramente te esta lanzando un error en la consola del firebug que dice "dsCall undefined" o algo semejante, cierto?
si es eso es porque no estas asignandole el "scope" adecuado, intenta de la siguiente manera:
..........(listener del combo que activa la carga del store)......... 'select' : { scope: this, fn : function(cmb, rec, idx) { this.textoLoc = rec.get('nombre'); this.dsCall.load({ params:{ provincia: this.textoProv, //provincia municipio: this.textoLoc, // municipio consulta: 'callejero', // tipo consulta tipo: 'json' // tipo de respuesta de proxyCatastro.php } }); }.createDelegate(this) //<--- le asignas el contexto }, ...............(fin del listener)..................mira, para poder ayudarte mejor dime que error te estan apareciendo en la consola, porque solamente le ando atiando jejejejejejeje.... saludos
Hola de nuevo:
Pues no era una cuestión de como se asignaba el contexto, sino de como estába construido el JSON.
Aunque estaba bien construido, no lo aceptaba y he modificado la salida de JSON desde php para obtener:
{"cuca":"26","calle":[{"loine":{"cp":"26","cm":"87"},"dir":{"cv":"24","tv":"LA","nv":"RIOJA"}},{"loine" :{"cp":"26","cm":"87"},"dir":{"cv":"1","tv":"CL","nv":"ALBERTO MARTIN"}},......]}Y así si funciona, Muchas gracias por todo. Por cierto yo para depurar solo utilizo Firebug, he leido en el sitio de Extjs que se pede depurar con extjs pero no se como. Te agradecería un tutorial dedicado a la depuración dentro de los buenísimos tutoriales que escribes. Muchas gracias de nuevo.
¿Conoces a alguien que pueda responder esta pregunta? Comparte el link en Twitter o Facebook
Es necesario registrarse para poder participar en el foro! Si ya tienes una cuenta puedes entrar y comentar en este foro.