ExtJS 4: TreeStore со статическими и динамически загруженными данными?
Я делаю TreePanel, который выглядит так:
на данный момент я его "переделала" со следующим кодом:
treePanel.setRootNode({
text: 'Root',
expanded: true,
children: [
{
text: 'General Settings',
icon: kpc.cfg.baseUrl.img+'/icon_gears-bluegreen.gif',
leaf: true
},
{
text: 'Users',
icon: kpc.cfg.baseUrl.img+'/icon_users-16x16.gif',
expanded: true,
children: [
{
text: 'Dummy User 1',
icon: kpc.cfg.baseUrl.img+'/icon_user-suit.gif',
leaf: true
},
{
text: 'Dummy User 2',
icon: kpc.cfg.baseUrl.img+'/icon_user-suit.gif',
leaf: true
},
{
text: 'Dummy User 3',
icon: kpc.cfg.baseUrl.img+'/icon_user-suit.gif',
leaf: true
},
{
text: 'Dummy User 4',
icon: kpc.cfg.baseUrl.img+'/icon_user-suit.gif',
leaf: true
}
]
}
]
});
как я могу динамически загружать отдельных пользователей (т. е. через магазин)? другими словами, как сделать TreeStore, который представляет собой смесь статических и динамически загружаемых элементов?
спасибо!
5 ответов
лучшим решением для меня было:
- создайте два дерева-одно со статическим содержимым, другое настроено для загрузки моих пользовательских моделей с сервера.
- "график" динамически загруженное дерево на статическое дерево.
Я написал небольшой учебник, который включает в себя runnable demo здесь (если кому-то нужен более подробный ответ), но на высоком уровне код выглядит так:
Ext.define('demo.UserModel', {
extend: 'Ext.data.Model',
fields: ['id', 'name', 'profile_image_url']
});
var userTreeStore = Ext.create('Ext.data.TreeStore', {
model: 'demo.UserModel',
proxy: {
type: 'jsonp',
url : 'https://myserver/getusers',
reader: {
type: 'json',
root: 'users'
}
},
listeners: {
// Each demo.UserModel instance will be automatically
// decorated with methods/properties of Ext.data.NodeInterface
// (i.e., a "node"). Whenever a UserModel node is appended
// to the tree, this TreeStore will fire an "append" event.
append: function( thisNode, newChildNode, index, eOpts ) {
// If the node that's being appended isn't a root node, then we can
// assume it's one of our UserModel instances that's been "dressed
// up" as a node
if( !newChildNode.isRoot() ) {
newChildNode.set('leaf', true);
newChildNode.set('text', newChildNode.get('name'));
newChildNode.set('icon', newChildNode.get('profile_image_url'));
}
}
}
});
userTreeStore.setRootNode({
text: 'Users',
leaf: false,
expanded: false // If this were true, the store would load itself
// immediately; we do NOT want that to happen
});
var settingsTreeStore = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
children: [
{
text: 'Settings',
leaf: false,
expanded: true,
children: [
{
text: 'System Settings',
leaf: true
},
{
text: 'Appearance',
leaf: true
}
]
}
]
}
});
// Graft our userTreeStore into the settingsTreeStore. Note that the call
// to .expand() is what triggers the userTreeStore to load its data.
settingsTreeStore.getRootNode().appendChild(userTreeStore.getRootNode()).expand();
Ext.create('Ext.tree.Panel', {
title: 'Admin Control Panel',
store: settingsTreeStore,
});
Я считаю node
параметр поможет вам. Set autoLoad: false
, а затем использовать beforerender
событие фактической панели дерева. Внутри события вызовите функцию загрузки магазина и передайте ей node
. Врачи заявляют, что если это опущено с load()
вызова, он будет по умолчанию для корневого узла. Казалось бы, вы можете оставить свои настройки в корневом узле, а затем, вызвав load и передав ему дочерний узел, вы сможете обновить только пользователей.
см.: http://docs.sencha.com/ext-js/4-0/#!/api / Ext.данные.TreeStore-method-load Для справки. Обратите внимание, что эта функция загрузки не такая, как в Ext.data.Store
(Ext.data.TreeStore
не наследуется от Ext.data.Store
).
у меня не было возможности проверить это, но, похоже, перспективный.
у меня очень похожая проблема, и хотя я не получил ее полностью, как я хочу, она в основном работает. У меня autoLoad: false
и добавил этот обработчик событий:
beforerender: function(comp, opts) {
var node = this.getRootNode();
node.appendChild({test: 'Recent', id: 'recent', expandable: true, expanded: false});
node.appendChild({text: 'Current', id: 'current', expandable: true, expanded: false});
node.appendChild({text: 'All', id: 'all', expandable: true, expanded: false});
}
3 непосредственных дочерних элемента корня статичны, затем прокси-сервер делает запрос на их заполнение, когда я их разворачиваю (передавая соответствующий идентификатор).
мне также пришлось подавить загрузку корневого узла с помощью прослушивателя на магазине:
listeners: {
beforeload: function(store, operation, opts) {
if (operation.node.data.id == 'root') {
return false;
}
}
},
надеюсь, что это помогает. Кажется, должен быть лучший способ!?!
вот моя функция для преобразования обычных данных в treeStore, вы можете использовать это. Таким образом, вам больше не нужен treeStore:
Records: массив записей. Текст: название элемента (получить из записи) Дети: имя детей (по умолчанию "дети")
dynamicReportsStore.load({
scope: this,
callback: function (records, operation) {
if (operation.isComplete()) {
var tree = this.buildTreeByRecords(records, 'name');
treePanel.getRootNode().removeAll();
treePanel.getRootNode().appendChild(tree);
}
}
});
buildTreeByRecords: function (records, text, children) {
var childs = [],
results = [],
tree = [];
records = Ext.Array.map(records, function (record) {
return {
text: record.get(text) || record.get('id'),
leaf: record.get('leaf'),
expanded: true,
parentId: record.get('parentId'),
id: record.get('id')
};
}, this);
Ext.each(records, function (record) {
if (Ext.isEmpty(childs[record.parentId])) {
childs[record.parentId] = [];
}
childs[record.parentId].push(record);
}, this);
Ext.each(records, function (record) {
if (!Ext.isEmpty(childs[record.id])) {
record[children || 'children'] = childs[record.id];
results.push(record);
}
}, this);
Ext.each(results, function (result) {
if (result.parentId === 0) {
tree.push(result);
}
}, this);
return tree;}
я использовал читателя для достижения этого эффекта в том, что я считаю элегантной модой. Имейте в виду, что это с плоским магазином и может выглядеть немного иначе с магазином дерева. Концепция должна быть переведена.
Ext.define('Ext.data.reader.a8PolicyReader', {
extend: 'Ext.data.reader.Json',
read: function(response) {
var staticStuff,
responseArr;
// Static stuff
staticStuff = [{name: 'some static user', id:1}, {name: 'another user', id:2}];
// extract response
responseArr = Ext.decode(response.responseText);
// shove them together
responseArr.concat(staticStuff);
// read
this.readRecords(responseArr);
}
})