ExtJS 4: TreeStore со статическими и динамически загружаемыми данными? - PullRequest
6 голосов
/ 21 сентября 2011

Я создаю TreePanel, которая выглядит следующим образом:

enter image description here

На данный момент у меня есть "макет" со следующим кодом:

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 ]

11 голосов
/ 26 сентября 2011

Лучшим решением для меня было:

  1. создать два хранилища дерева - одно со статическим содержимым, другое настроено для загрузки моих пользовательских моделей с сервера.
  2. «отобразить» динамически загружаемое дерево на статическое дерево.

Я написал небольшое руководство, которое включает в себя работающую демонстрацию здесь (на случай, если кто-то захочет получить более подробную информацию).ответ), но на высоком уровне код выглядит так:

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,
});
2 голосов
/ 22 сентября 2011

У меня очень похожая проблема, и хотя я не заставил ее работать так, как мне бы хотелось, она в основном работает. Я 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;
                }
            }               
        },

Надеюсь, это поможет. Кажется, должен быть лучший путь!?!

2 голосов
/ 21 сентября 2011

Я верю, что параметр node поможет вам.Установите autoLoad: false, затем используйте событие beforerender фактической панели дерева.Внутри события вызовите функцию загрузки магазина и передайте ей node.Документы утверждают, что, если это опущено в вызове load(), по умолчанию это будет корневой узел.Может показаться, что вы можете оставить свои настройки в корневом узле, а затем, вызвав load и передав ему дочерний узел, вы сможете обновить только пользователей.

См. * 1009.* для справки.Обратите внимание, что эта функция загрузки отличается от Ext.data.Store (Ext.data.TreeStore не наследуется от Ext.data.Store).

У меня не было возможности проверить это, но она выглядит многообещающей.

1 голос
/ 18 мая 2012

Вот моя функция для преобразования обычных данных в данные treeStore, вы можете использовать это. Таким образом, вам больше не нужен treeStore:

Записи: массив записей. Текст: название предмета (получить из записи) Дети: имя детей (по умолчанию «дети»)

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;}
0 голосов
/ 22 сентября 2013

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

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