我正在测试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响应看起来像这样(只显示'快照'节点):
{
"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和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时都不会显示,但是如果我从快照模型中删除关联并只添加另一个名为'models'的字段,它就可以了。
使用关联时,正确显示模型列表的最佳做法是什么?
我是否必须使用嵌套模板和自定义函数来执行此操作?
好问题(+1)
似乎直接在XTemplate中使用关联是不可能的(今天)因为XTemplate需要对象数组。 (当你有关联时,这不再是真的)
你有三个选择 -
- 摆脱像你这样的社团
提及。 (听起来不好'
但会工作)
- 如果您有使用模板的数据视图,请覆盖 Ext.view.AbstractView.prepareData 并从模型中创建对象数组
- 在调用apply之前,迭代snapshotStore.getRange()并(重新)生成具有“models”属性的对象并将此数组传递给
.apply
好问题(+1)
似乎直接在XTemplate中使用关联是不可能的(今天)因为XTemplate需要对象数组。 (当你有关联时,这不再是真的)
你有三个选择 -
- 摆脱像你这样的社团
提及。 (听起来不好'
但会工作)
- 如果您有使用模板的数据视图,请覆盖 Ext.view.AbstractView.prepareData 并从模型中创建对象数组
- 在调用apply之前,迭代snapshotStore.getRange()并(重新)生成具有“models”属性的对象并将此数组传递给
.apply
我应该指出,从4.1开始,模型记录有一个名为的方法 getData()
,如果使用 getData( true )
还将返回相关数据。
我完全同意模板看起来像这样是理想的。但是,实际上很容易让模板通过关联来执行您想要的操作。模型在根级别的名为data和association的属性中保存其所有字段,其约定为: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>'
);
您可以侦听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;
}
}
}
就像@Izhaki说的那样,在记录上使用getData(true)将数据传递给模板,然后对@Aaron所说的循环数据进行变换。例如,如果模板是容器的一部分:
//...
tpl: //your tpl
data: record.getData(true)
//....
此模板代码段应该可以正常工作:
'<tpl for="models">',
'<p>{name} - {description}</p>',
'</tpl>'
根据我最近的经验,如果你不在商店工作,你不应该有问题。
ExtJS 4文档中的XTemplate示例运行正常(至少对我而言)。您可以为这些数据添加模型,该示例将正在进行中。
我试图通过商店做同样的事情。将store.first()。数据传递给overwrite(...)XTemplate方法时,关联不在该结构中。
您可以签入以下代码:
var data = {
name : 'Tommy Maintz',
title : 'Lead Developer',
company : 'Sencha Inc.',
email : 'tommy@sencha.com',
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-Associations有多糟糕) http://www.sencha.com/forum/showthread.php?127320-FIXED-EXTJSIV-242-multiple-HasMany-association-conflict-in-XTemplate。
抱歉不提供解决方案:(
我会