extjs 4 XTemplate 类关联

发布于 2024-11-17 03:56:11 字数 1925 浏览 4 评论 0 原文

我正在测试 extjs 4,我偶然发现了一些东西,我似乎无法弄清楚。

我有简单的对象关联:Snapshot - hasMany ->模型

现在,我尝试使用 XTemplate 在视图组件中显示此关联,因此我的 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 引入的模型的概念我已经为快照和模型创建了模型,并根据 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 时不会显示任何模型,但是如果我从快照模型中删除关联并仅添加另一个名为“模型”的字段它工作正常。

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

I'm testing out extjs 4 and I have stumbled upon something, I can't seem to figure out.

I have simple object association: Snapshot - hasMany -> Model

Now, I am trying to use XTemplate to show this association in View component, so I have my XTemplate looking like this:

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>'
);

And my JSON response looks like this (showing just 'snapshot' 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"
            }
        ]
    }

As extjs 4 introduces concept of Model I have created models for Snapshot and Model and created association according to API docs.

Snapshot model:

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

Model model ;P

Ext.define('Model', {
    extend: 'Ext.data.Model',
    belongsTo: 'Snapshot',
    fields: [
        { name: 'id',  type: 'int' },
        { name: 'snapshot_id', type: 'int' },            
        'name',
        'description'
    ],
    idProperty: 'id'
});

And this is where my problem lies - When I use this setup, none of my models is displayed when XTemplate is being executed, however if I remove associations from Snapshot model and just add another field called 'models' it works OK.

What is the best practise to display list of models correctly while using associations?
Would I have to use nested templates and custom functions to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

美胚控场 2024-11-24 03:56:11

好问题(+1)

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

你有三个选择 -

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

Good Question (+1)

It seems using the associations directly in the XTemplate is not possible (today) because XTemplate expects array of objects. (When you have associations, this is no longer true)

You have three options -

  1. Get rid of associations like you
    mentioned. (does not 'sound' good
    but will work)
  2. If you have a data view using the template, override Ext.view.AbstractView.prepareData and create array of objects from your models
  3. Before you call apply, iterate over the snapshotStore.getRange() and (re)generate objects with "models" attribute and pass this array to .apply
你是年少的欢喜 2024-11-24 03:56:11

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

I should point out that as of 4.1, a model record has a method called getData(), which if called using getData( true ) will also return the associated data.

探春 2024-11-24 03:56:11

我完全同意模板看起来像这样是理想的。然而,实际上很容易获得一个模板来执行您想要的关联操作。模型将其所有字段保存在根级别的称为数据和关联的属性中,并遵循以下约定: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>'
);

I totally agree it would be ideal to have templates look like this. However, it's actually quite easy to get a template to do what you want with associations. Models hold all of their fields within a property called data and associations at the root level with the convention: associationName+'Store'. Therefore, all you need to do is write your template as follows:

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>'
);
无名指的心愿 2024-11-24 03:56:11

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

You can listen on the store.load event and add the associated data back to the store record, and then the template will work (I did this using the RowExpander's 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;
        }
    }
}
葬花如无物 2024-11-24 03:56:11

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

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

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

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

Like @Izhaki says use getData(true) on the record to pass the data to the template, then do a variation of what @Aaron says to loop thru the data. For example, if the template is part of a container:

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

This template snippet should work fine:

 '<tpl for="models">',
 '<p>{name}  - {description}</p>',
 '</tpl>'
远昼 2024-11-24 03:56:11

根据我最近的经验,如果您不通过商店工作,就不应该遇到问题。
ExtJS 4 文档中的 XTemplate 示例工作正常(至少对我来说)。您可以为这些数据添加模型,示例将继续运行。

我尝试通过一家商店做同样的事情。当您将 store.first().data 传递给 overwrite(...) 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-Associations 的工作有多糟糕)http://www.sencha.com/forum/showthread.php?127320-FIXED-EXTJSIV-242-multiple-HasMany-association-conflict-in-XTemplate

抱歉没有提供解决方案:(

willy

from my very recent experience, you shouldn't have problems if you are NOT working through stores.
The XTemplate example from ExtJS 4 docs works ok (at least for me). You can add a model for those data and the example will be working on.

I tried to do the same through a store. When you pass the store.first().data to the overwrite(...) XTemplate method, the associations are not in that structure.
You can check in the following code:

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)
}

You can also can try (to see how bad XTemplate-Store-Associations work) at http://www.sencha.com/forum/showthread.php?127320-FIXED-EXTJSIV-242-multiple-HasMany-association-conflict-in-XTemplate.

sorry not to provide a solution : (

w i l l y

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文