extjs 4 ассоциации классов XTemplate - PullRequest
11 голосов
/ 24 июня 2011

Я тестирую 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, я создал модели для 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, однако, если я удаляю ассоциации из модели Snapshot и просто добавляю другое поле под названием «models», все работает нормально.

Как лучше всего правильно отображать список моделей при использовании ассоциаций? Нужно ли использовать для этого вложенные шаблоны и пользовательские функции?

Ответы [ 6 ]

7 голосов
/ 24 июня 2011

Хороший вопрос (+1)

Кажется, использование связей непосредственно в XTemplate невозможно (сегодня), потому что XTemplate ожидает массив объектов. (Если у вас есть ассоциации, это больше не так)

У вас есть три варианта -

  1. Избавься от таких ассоциаций, как ты упоминается. (не звучит хорошо но будет работать)
  2. Если у вас есть представление данных с использованием шаблона, переопределите Ext.view.AbstractView.prepareData и создайте массив объектов из ваших моделей
  3. Прежде чем вызывать apply, выполните итерацию по snapshotStore.getRange () и (повторно) создайте объекты с атрибутом "models" и передайте этот массив в .apply
3 голосов
/ 20 февраля 2013

Следует отметить, что начиная с 4.1, запись модели имеет метод с именем getData(), который при вызове с использованием getData( true ) также возвращает связанные данные.

2 голосов
/ 08 марта 2013

Я полностью согласен, что было бы идеально, чтобы шаблоны выглядели так. Однако на самом деле довольно легко получить шаблон, который будет делать то, что вы хотите с ассоциациями. Модели хранят все свои поля в свойстве, называемом данными и ассоциациями, на корневом уровне с соглашением: 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>'
);
0 голосов
/ 24 апреля 2013

Как @Izhaki говорит, использовать getData (true) для записи, чтобы передать данные в шаблон, а затем сделать изменение того, что @Aaron говорит для цикла через данные.Например, если шаблон является частью контейнера:

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

Этот фрагмент шаблона должен работать нормально:

 '<tpl for="models">',
 '<p>{name}  - {description}</p>',
 '</tpl>'
0 голосов
/ 11 августа 2011

из моего недавнего опыта у вас не должно быть проблем, если вы НЕ работаете через магазины. Пример XTemplate из ExtJS 4 docs работает нормально (по крайней мере, для меня). Вы можете добавить модель для этих данных, и пример будет работать.

Я пытался сделать то же самое через магазин. При передаче данных store.first (). В метод XTemplate overwrite (...) ассоциации не входят в эту структуру. Вы можете проверить следующий код:

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.

извините, что не предоставили решение: (

w l l y

0 голосов
/ 15 июля 2011

Вы можете прослушать событие store.load и добавить связанные данные обратно в запись хранилища, и тогда шаблон будет работать (я сделал это с помощью rowBodyTpl RowExpander).

listeners: {
    load: function(store,storeRecs) {
        var i,r;
        for (i=0;i<storeRecs.length;i++) {
            r = storeRecs[i];
            r.data.subItem = r.getAssociatedData().subItem;
        }
    }
}
...