Extjs 4 Ассоциации классов XTemplate
Я тестирую extjs 4, и я наткнулся на что-то, я не могу понять.
У меня есть простая ассоциация объектов: Снимок - hasMany → Модель
Теперь я пытаюсь использовать XTemplate для отображения этой ассоциации в компоненте View, поэтому у меня есть XTemplate, выглядящий так:
Ext.create('Ext.XTemplate',
'<tpl for=".">',
'<div class="snapshot" id="{id}">',
'<h1>{snapshot}</h1>',
'<p><span class="label">Created: </span>{dateString}</p>',
'<p><span class="label">Models</span></p>',
'<tpl for="models">',
'<p>{name} - {description}</p>',
'</tpl>',
'</div>',
'</tpl>',
'<div class="x-clear bottompad"></div>'
);
И мой ответ JSON выглядит так (показывает только "моментальный снимок" node):
{
"id": 1,
"snapshot": "Snapshot 1",
"created": 1305806847000,
"models": [
{
"id": 1,
"name": "ABC",
"description": "A B C"
}, {
"id": 111,
"name": "ABCDD",
"description": "A B C XCXC"
}
]
}
Как extjs 4 вводит концепцию Model I, я создал модели для Snapshot and Model и создал ассоциацию в соответствии с документами API.
Модель снимка:
Ext.define('Snapshot', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
'snapshot',
{name: 'created',type: 'date', dateFormat: 'time' }
],
associations:[
{type: 'hasMany', model: 'Model', name: 'models'}
],
idProperty: 'id'
});
Модель модели; P
Ext.define('Model', {
extend: 'Ext.data.Model',
belongsTo: 'Snapshot',
fields: [
{ name: 'id', type: 'int' },
{ name: 'snapshot_id', type: 'int' },
'name',
'description'
],
idProperty: 'id'
});
И вот здесь моя проблема. Когда я использую эту настройку, ни одна из моих моделей не отображается при выполнении XTemplate, однако, если я удалю ассоциации из модели моментальных снимков и просто добавлю другое поле под названием "модели", оно работает нормально.
Какова наилучшая практика отображения списка моделей при использовании ассоциаций?
Должен ли я использовать вложенные шаблоны и настраиваемые функции для этого?
Ответы
Ответ 1
Хороший вопрос (+1)
Кажется, использование ассоциаций непосредственно в XTemplate невозможно (сегодня), потому что XTemplate ожидает массив объектов. (Когда у вас есть ассоциации, это уже не так)
У вас есть три варианта -
- Избавьтесь от таких ассоциаций, как вы
упоминается. (не "звучит" хорошо
но будет работать)
- Если у вас есть представление данных с использованием шаблона, переопределите Ext.view.AbstractView.prepareData и создайте массив объектов из ваших моделей
- Прежде чем вы назовете применить, выполните итерацию по snapshotStore.getRange() и (re) сгенерируйте объекты с атрибутом "models" и передайте этот массив в
.apply
Ответ 2
Следует отметить, что с 4.1 модельная запись имеет метод под названием getData()
, который, если вызываемый с помощью getData( true )
также возвращает связанные данные.
Ответ 3
Я полностью согласен, что было бы идеально, если бы шаблоны выглядели так. Однако на самом деле довольно легко получить шаблон, чтобы делать то, что вы хотите, с ассоциациями. Модели содержат все свои поля внутри свойства, называемого данными и ассоциациями на корневом уровне, с помощью соглашения: associationName + 'Store'. Поэтому все, что вам нужно сделать, это написать свой шаблон следующим образом:
var template = Ext.create('Ext.XTemplate',
'<tpl for=".">',
'<div class="snapshot" id="{data.id}">',
'<h1>{data.snapshot}</h1>',
'<p><span class="label">Created: </span>{data.created}</p>',
'<p><span class="label">Models</span></p>',
'<tpl for="modelsStore">',
'<p>{data.name} - {data.description}</p>',
'</tpl>',
'</div>',
'</tpl>',
'<div class="x-clear bottompad"></div>'
);
Ответ 4
Вы можете прослушивать событие store.load и добавлять связанные данные обратно в запись хранилища, а затем шаблон будет работать (я сделал это с помощью строки RowExpander rowBodyTpl).
listeners: {
load: function(store,storeRecs) {
var i,r;
for (i=0;i<storeRecs.length;i++) {
r = storeRecs[i];
r.data.subItem = r.getAssociatedData().subItem;
}
}
}
Ответ 5
Как и @Izhaki говорит использовать getData (true) в записи для передачи данных в шаблон, а затем сделать вариацию того, что @Aaron говорит, чтобы пройти через данные. Например, если шаблон является частью контейнера:
//...
tpl: //your tpl
data: record.getData(true)
//....
Этот фрагмент шаблона должен работать нормально:
'<tpl for="models">',
'<p>{name} - {description}</p>',
'</tpl>'
Ответ 6
из моего недавнего опыта, у вас не должно быть проблем, если вы НЕ работаете через магазины.
Пример XTemplate из документов ExtJS 4 работает нормально (по крайней мере для меня). Вы можете добавить модель для этих данных, и пример будет работать.
Я пытался сделать то же самое через магазин. Когда вы передаете данные store.first() в метод перезаписи (...) XTemplate, ассоциации не входят в эту структуру.
Вы можете проверить следующий код:
var data = {
name : 'Tommy Maintz',
title : 'Lead Developer',
company : 'Sencha Inc.',
email : '[email protected]',
address : '5 Cups Drive',
city : 'Palo Alto',
state : 'CA',
zip : '44102',
drinks : ['Coffee', 'Soda', 'Water'],
kids : [{
name : 'Joshua',
age : 3
}, {
name : 'Matthew',
age : 2
}, {
name : 'Solomon',
age : 0
}]
};
var kidsModelProps = {
extend: "Ext.data.Model",
fields: [
"name",
{name: "age", type: "int"}
]
}
Ext.define ("KidsModel", kidsModelProps)
var datamodelProps = {
extend: "Ext.data.Model",
fields: [
"name", "title", "company", "email", "address",
"city", "state", "zip", "drinks"
],
hasMany: {name: "thekids", model: "KidsModel"},
proxy: {
type: "memory",
reader: {
type: "json"
}
}
}
Ext.define ("DataModel", datamodelProps)
var kidsStore = new Ext.data.Store({
data: data,
storeId: "kidsStore",
model: "DataModel"
})
var tpl = new Ext.XTemplate(
'<p>Name: {name}</p>',
'<p>Title: {title}</p>',
'<p>Company: {company}</p>',
'<p>Kids: ',
'<tpl for="kids">', // interrogate the kids property within the data
'<p>{name}</p>',
'</tpl></p>'
);
Ext.onReady(function () {
var thePanel = Ext.create ("Ext.panel.Panel", {
html: "<b>Viewport tpl-test: build with separated files</b>",
border: 10,
height: 500,
layout: {
type: 'vbox',
align: 'center'
},
renderTo: Ext.getBody(),
bodyStyle: "background-color: yellow",
items: []
})
var someData = kidsStore.first().data
tpl.overwrite (thePanel.body, someData)
}
Вы также можете попробовать (посмотреть, как работают плохие ассоциации XTemplate-Store) в http://www.sencha.com/forum/showthread.php?127320-FIXED-EXTJSIV-242-multiple-HasMany-association-conflict-in-XTemplate.
жаль, что не предоставил решение: (
w я l l y