Sencha Touch 2 вложенные модели и хранилища данных
Я даже не знаю, как спросить об этом, но здесь.
У меня две модели: Platter, содержащая много рецептов:
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' }
]
}
});
Платтеры - это в основном разные фильтры в онлайн-магазине рецептов. Поэтому у меня может быть тысяча рецептов, но мое блюдо "Пицца" вернет только рецепты пиццы (таким образом, filterProperty). Платтеры только создаются и хранятся локально, а Рецепты - в режиме онлайн. Итак, магазины:
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',
}
}
}
});
Теперь я хотел бы создать dataview of dataviews. Список Platters, каждый из которых содержит список рецептов:
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);
}
}
});
Теперь, как мне заполнить рецепты блюд? Если я заполню Platters небольшим количеством данных в виде строки, например:
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'}
]
... он работает прямо и отображает данные с пастой в нем. Поэтому мне просто нужно знать, как заставить мои пластинки заполнять их данные рецепта. Где (я предполагаю, что в контроллере какое-то событие инициализации) и как его подключить? И правильно ли использую filterProperty? Я не полностью понимаю документы по этому поводу, но я думаю, что он обычно фильтрует внешний ключ, которого у меня нет, и что filterProperty переопределяет это. Так что URL будет содержать & text = лапшу, добавленную к нему.
Спасибо заранее.
Ответы
Ответ 1
Это, по-видимому, не использует структуру ассоциации и хранилища, которая, как мне кажется, имеет Sencha Touch, но даже после перехода к правильной загрузке ассоциации recipes()
, я никогда не смогу ее получить чтобы обновить dataview. Я потратил слишком много времени на это, поэтому я пошел с менее элегантным решением. Я передаю текст фильтра установщику на Platter, который устанавливает его с этим фильтром в параметре. Он работает как минимум!
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);
}
});