Sencha Touch 2 modelos anidados y almacenes de datos

Apenas sé cómo preguntar esto, pero aquí va.

Tengo dos modelos, un Plato que contiene muchas Recetas:

Ext.define('NC.model.Platter', {
  extend: 'Ext.data.Model',
  config: {
    fields: [
      { name: 'name', type: 'string' },
      { name: 'text', type: 'string' }
    ],
    associations: [
      {type: 'hasMany', model: 'NC.model.Recipe', name: 'recipes', filterProperty: 'text'}
    ]
  }
});

Ext.define('NC.model.Recipe', {
  extend: 'Ext.data.Model',
  config: {
      fields: [
        { name: 'name', type: 'string' },
        { name: 'image', type: 'string' },
        { name: 'stepsText', type: 'string', mapping: 'properties.preparationText' },
        { name: 'ingredientsText', type: 'string', mapping: 'properties.ingredientsText' }
      ]
    }
});

Los platos son básicamente filtros diferentes en una tienda de recetas en línea. Entonces, podría tener mil recetas, pero mi fuente de 'Pizza' solo devolverá recetas de pizza (por lo tanto, la propiedad de filtro). Los platos se crean y almacenan localmente, mientras que las recetas están en línea. Entonces, las tiendas:

Ext.define('NC.store.Platters', {
  extend: 'Ext.data.Store',

  config: {
    model: 'NC.model.Platter',
    storeId: 'Platters',
    proxy: {
      type: 'localstorage',
      id: 'platters'
    },
    data : [
        {name: 'Noodles', text: 'noodle'},
        {name: 'Baked', text: 'bake'},
        {name: 'Pizza', text: 'pizza'}
    ]
  }
});

Ext.define('NC.store.Recipes', {
  extend: 'Ext.data.Store',

  config: {
    model: 'NC.model.Recipe',
    storeId: 'Recipes',
    proxy: {
      type: 'jsonp',
      url: 'xxxx',  // url here (redacted)
      callbackKey: 'callback',
      filterParam: 'text',
      extraParams: {
        // credentials and tokens here (redacted)
      },
      reader: {
        type: 'json',
        idProperty: 'uuid',
      }
    }
  }
});

Ahora, me gustaría crear una vista de datos de vistas de datos. Una lista de platos, cada uno con su lista de recetas:

Ext.define('NC.view.DiscoverGrid', {
  extend: 'Ext.DataView',
  xtype: 'discovergrid',
  id: 'discover',

config: {
    title: 'Discover',
    baseCls: '',
    useComponents: true,
    defaultType: 'platter',
    store: 'Platters',
    ui: 'light'
  }
});

Ext.define('NC.view.Platter', {
  extend: 'Ext.dataview.component.DataItem',
    xtype: 'platter',

  config: {
      layout: 'fit',
      height: '100px',
      list: {
        itemTpl: '{name}',
        inline: true,
        scrollable: {
          direction: 'horizontal',
          directionLock: true
        }
      },
      dataMap: {
        getList: {
          setData: 'recipes'
        }
      }
    },

    applyList: function(config) {
      return Ext.factory(config, Ext.DataView, this.getList());
    },

  updateList: function(newList, oldList) {
    if (newList) {
        this.add(newList);
      }

  if (oldList) {
        this.remove(oldList);
      }
    }
  });

Ahora, ¿cómo completo las recetas del plato? Si relleno los platos con algunos datos de recetas en línea como, por ejemplo:

data : [
    {name: 'Noodles', text: 'noodle', recipes: [
      { name: 'Pasta', ingredientsText: "Tomatoes\nPassata\n1tsp Oregano", preparationText: "Do something\nAdd passata\nmix in oregano and tomato",
        ingredients: [{ text: "bla"}]
      }
    ]},
    {name: 'Baked', text: 'bake'},
    {name: 'Pizza', text: 'pizza'}
]

... funciona directamente y representa la vista de datos con Pasta en ella. Entonces, solo necesito saber cómo hacer que mis platos llenen sus datos de recetas. ¿Dónde (supongo que en un controlador en un evento de inicialización de algún tipo) y cómo conecto esto? ¿Y estoy usando filterProperty correctamente? No entiendo completamente los documentos sobre esto, pero creo que generalmente filtra en una clave externa, que no tengo, y que filterProperty anula esto. Para que la URL tenga &text=noodle adjunto.

Gracias de antemano.

preguntado el 22 de mayo de 12 a las 15:05

1 Respuestas

Esto ciertamente no parece estar utilizando la estructura de asociación y tienda que creo que tiene Sencha Touch, pero incluso después de progresar hasta el punto de obtener el recipes() asociación para cargar correctamente, nunca pude hacer que esto activara la actualización de la vista de datos. Le estaba dedicando demasiado tiempo, así que opté por una solución menos elegante. Paso el texto del filtro a un colocador en el plato que establece su almacenamiento con este filtro en el parámetro. ¡Funciona al menos!

Ext.define('NC.view.PlatterDataItem', {
  extend: 'Ext.dataview.component.DataItem',
  xtype: 'platterdataitem',


  config: {
    layout: 'vbox',
    height: '130px',
    cls: 'platter',
    list: {
    },
    dataMap: {
      getList: {
        setRecipeFilters: 'text'
      }
    }
  },

  applyList: function(config) {
    return Ext.factory(config, NC.view.Platter, this.getList());
  },

  updateList: function(newList, oldList) {
    if (newList) {
      this.add(newList);
    }


    if (oldList) {
      this.remove(oldList);
    }
  }
});

Ext.define('NC.view.Platter', {
  extend: 'Ext.DataView',
  xtype: 'platter',


  config: {
    layout: 'vbox',
    height: '130px',
    itemCls: 'platter-item',
    itemTpl:  '<div class="thumb"><tpl if="image != null"><img src="{image}" /></tpl></div>'+
              '<div class="name">{name}</div>',
    inline: {
      wrap: false
    },
    scrollable: {
      direction: 'horizontal',
      directionLock: true
    }
  },

  setRecipeFilters: function(text) {
    var store = Ext.create('Ext.data.Store', {
      model: 'NC.model.Recipe',
      autoLoad: true,
      proxy: {
        type: 'jsonp',
        url: 'xxxxx',
        callbackKey: 'callback',
        extraParams: {
          // credentials & text filter param
        },
        reader: {
          type: 'json',
          idProperty: 'uuid',
        }
      }
    });

    this.setStore(store);
  }
});

contestado el 29 de mayo de 12 a las 14:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.