2011-10-09 15 views
8

He estado tratando de resolver esto toda la noche, pero fue en vano. Tengo una estructura JSON como sigue (procedente de otro sistema, de modo que no puedo cambiar su estructura):¿Cómo se lee la estructura JSON anidada con un modelo de datos Sencha Touch?

 

    { 
     "parents":{ 
      "parent":[ 
      { 
       "parentId":1, 
       "children":{ 
        "child":[ 
         { 
          "childId":1, 
         }, 
         { 
          "childId":2, 
         } 
        ] 
       } 
      }, 
      { 
       "parentId":2, 
       "children":{ 
        "child":[ 
         { 
         "childId":1, 
         }, 
         { 
         "childId":2, 
         } 
        ] 
       } 
      } 
      ], 
      "pageNum":1, 
      "pageSize":2 
     } 
    } 

Sin embargo, no puedo entender por qué la estructura correcta de los modelos de datos debe ser. He intentado lo siguiente, pero no funciona. Por cierto, puedo acceder a la información de los padres. El problema es acceder a la información del niño. Entonces, creo que hay algo mal con la forma en que he configurado los datos de la relación.

 

    Ext.regModel("ParentModel", { 
     hasMany: { 
      model: 'ChildrenModel', 
      name: 'children.child' // not too sure about this bit 
     }, 
     fields: [ 
      {name: 'parentId', type: 'string'} 
     ], 

     proxy: { 
      type: 'ajax', 
      url : 'models.json', 
      reader: { 
       type: 'json', 
       root: 'parents.parent' // this works fine 
      } 
     } 
    }); 

    Ext.regModel('ChildrenModel', { 
     belongsTo: 'ParentModel', // not too sure about this bit 
     fields: [{name: 'childId', type: 'string'}] 
    }); 

con un almacén de datos:

 

    Ext.regStore('ParentModelStore', { 
     model: 'ParentModel', 
     autoLoad:true 
    }); 

estoy usando la siguiente plantilla que me obtiene la información de los padres, pero no puedo obtener los datos secundarios de él:

 

    myapp.views.ParentView = Ext.extend(Ext.Panel, { 
     layout: 'card', 

     initComponent: function() { 
      this.list = new Ext.List({ 
       itemTpl: new Ext.XTemplate(
        '<tpl for=".">', 
         '<div>', 
          '{parentId}', // this works fine 
         '</div>', 
         '<tpl for="children.child">', // this doesn't work 
           {childId} 
         '</tpl>', 
        '</tpl>', 
       ), 
       store: 'ParentStore', 
      }); 

      this.listpanel = new Ext.Panel({ 
       layout: 'fit', 
       items: this.list, 
      }); 

      this.items = this.listpanel; 

      myapp.views.ParentView.superclass.initComponent.apply(this, arguments); 
     }, 

    }); 

    Ext.reg('ParentView', myapp.views.ParentView); 

Lo que estoy luchando es el hecho de que los elementos "hijo" y "padre" están rodeados por otro elemento, "hijos" y "padres", respectivamente.

Cualquier ayuda muy apreciada.

Gracias de antemano,

Philip

PS Si quito los "niños" exteriores elemento de envolver y dejar el elemento interior "niño" (y el cambio "children.child" a "niño" en la definición del modelo) el código funciona bien.

PPS Estoy respondiendo a mi propia pregunta:

Doh! Olvidé agregar el elemento "niños" a los campos de ParentModel.

Debe ser como sigue (nota: no es necesario especificar el 'hasMany' o elementos de 'asociaciones' - no muy seguro de por qué esto es o cuál es el beneficio de incluirlos):

 

    Ext.regModel("ParentModel", { 
     fields: [ 
      {name: 'parentId', type: 'string'}, 
      {name: 'children'} // VERY IMPORTANT TO ADD THIS FIELD 
     ], 

     proxy: { 
      type: 'ajax', 
      url : 'models.json', 
      reader: { 
       type: 'json', 
       root: 'parents.parent' // this works fine 
      } 
     } 
    }); 

    Ext.regModel('ChildrenModel', { 
     fields: [{name: 'childId', type: 'string'}] 
    }); 

La plantilla funciona muy bien también:

 

    '<tpl for="children.child">', // this syntax works too. 
      {childId} 
    '</tpl>', 

Respuesta

7

He añadido un convertidor para permitir el acceso a los datos de plantilla en el modelo consistente sin importar si un solo objeto o una matriz es devuelto.

Ext.regModel("ParentModel", { 
     fields: [ 
      {name: 'parentId', type: 'string'}, 
      {name: 'children', convert: 
      function(value, record) { 
       if (value.child) { 
        if (value.child instanceof Array) { 
         return value.child; 
        } else { 
         return [value.child]; // Convert to an Array 
        } 
       } 

       return value.child; 
      } 
     } 
     ], 

     proxy: { 
      type: 'ajax', 
      url : 'models.json', 
      reader: { 
       type: 'json', 
       root: 'parents.parent' // this works fine 
      } 
     } 
    }); 

Nota: Realmente no necesito definir ChildrenModel. Creo que puedo escapar sin definirlo, ya que Sencha debe escribir automáticamente convirtiéndolo.

11

encontramos con un problema similar recently..I pensar.

Debe especificar la asignación a los datos que desea en su modelo. Por ejemplo:

Ext.regModel('Album', { 
fields: [ 
    {name: 'artist_name', mapping: 'album.artist.name'}, 
    {name: 'artist_token', mapping: 'album.artist.token'}, 
    {name: 'album_name', mapping: 'album.name'}, 
    {name: 'token', mapping: 'album.token'}, 
    {name: 'small_cover_url', mapping: 'album.covers.s'}, 
    {name: 'large_cover_url', mapping: 'album.covers.l'} 
]/*, 
getGroupString : function(record) { 
    return record.get('artist.name')[0]; 
},*/ 

});

consume este JSON:

{ 
    "album":{ 
    "covers":{ 
     "l":"http://media.audiobox.fm/images/albums/V3eQTPoJ/l.jpg?1318110127", 
     "m":"http://media.audiobox.fm/images/albums/V3eQTPoJ/m.jpg?1318110127", 
     "s":"http://media.audiobox.fm/images/albums/V3eQTPoJ/s.jpg?1318110127" 
    }, 
    "artist":{ 
     "name":"New Order", 
     "token":"OyOZqwkN" 
    }, 
    "name":"(The Best Of)", 
    "token":"V3eQTPoJ" 
    } 

},


+0

Genial: la asignación funciona, sin embargo, todavía tenía un problema ya que a veces se devuelve un solo objeto y, a veces, se devuelve una matriz. He incluido otra respuesta a continuación con la solución que he elegido por el momento. –