2012-05-22 30 views
10

Apenas si sé cómo preguntar esto, pero aquí va.Sencha Touch 2 modelos anidados y almacenes de datos

que tienen 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' } 
     ] 
    } 
}); 

fuentes son básicamente diferentes filtros en una tienda de recetas en línea. Así que podría tener mil recetas, pero mi plato de "Pizza" solo devolverá recetas de pizza (por lo tanto, filterProperty). Los platos se acaban de crear y almacenar 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 dataviews. Una lista de los Platters, 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 lo pueblan las recetas del plato? Si pueblan los Platters con un poco de datos de recetas en línea como, por lo que:

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 hacia fuera y hace que el DataView con pasta en ella. Así que 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 lo conecto? ¿Y estoy usando filterProperty correctamente? No entiendo completamente los documentos sobre esto, pero creo que generalmente filtra una clave externa, que no tengo, y que filterProperty anula esto. De modo que la URL tendrá & texto = fideo adjunto.

Gracias de antemano.

Respuesta

0

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 la asociación recipes() para cargar correctamente, no podría hacer que esto desencadenara la vista de datos para actualizar. Estaba gastando demasiado tiempo en eso, 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 parametro. ¡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); 
    } 
});