extjs 4 XTemplate类关联

时间:2011-06-24 12:39:34

标签: extjs model extjs4 model-associations

我正在测试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时都不会显示,但是如果我从快照模型中删除关联并只添加另一个名为“模型”的字段,则它可以正常工作。

使用关联时正确显示模型列表的最佳做法是什么? 我是否必须使用嵌套模板和自定义函数来执行此操作?

6 个答案:

答案 0 :(得分:7)

好问题(+1)

似乎直接在XTemplate中使用关联是不可能的(今天)因为XTemplate需要对象数组。 (当你有关联时,这不再是真的)

您有三种选择 -

  1. 摆脱像你这样的社团 提及。 (听起来不好' 但会工作)
  2. 如果您使用模板有数据视图,请覆盖Ext.view.AbstractView.prepareData并从模型中创建对象数组
  3. 在调用apply之前,迭代snapshotStore.getRange()并(重新)生成具有“models”属性的对象,并将此数组传递给.apply

答案 1 :(得分:3)

我应该指出,从4.1开始,模型记录有一个名为getData()的方法,如果使用getData( true )进行调用,也会返回相关数据。

答案 2 :(得分:2)

我完全同意让模板看起来像这样是理想的。但是,实际上很容易让模板通过关联来执行您想要的操作。模型将所有字段保存在根级别的数据和关联属性中,具有约定: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>'
);

答案 3 :(得分:0)

您可以侦听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;
        }
    }
}

答案 4 :(得分:0)

就像@Izhaki所说,在记录上使用getData(true)将数据传递给模板,然后对@Aaron所说的循环数据进行变换。例如,如果模板是容器的一部分:

 //...
 tpl: //your tpl
 data: record.getData(true)
 //....

此模板代码段应该可以正常工作:

 '<tpl for="models">',
 '<p>{name}  - {description}</p>',
 '</tpl>'

答案 5 :(得分:-1)

从我最近的经历来看,如果你不在商店工作,你不应该有问题。 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)
}

你也可以在http://www.sencha.com/forum/showthread.php?127320-FIXED-EXTJSIV-242-multiple-HasMany-association-conflict-in-XTemplate尝试(看看XTemplate-Store-Associations有多糟糕)。

抱歉不提供解决方案:(

我喜欢