2

Lets say I have a Ext.tree.TreePanel object, and it has data loaded from an external file, ex:

var tree = new Ext.tree.TreePanel({
    ...
    loader: new Ext.tree.TreeLoader({
        dataUrl:'./some_file.json'
    }),
    ...
});

This file is an array of objects that define the tree.

Lets say the user adds new nodes to the tree and moves some nodes around. Is there away to get the JSON data from the tree so that it could be used for the next time the user loads the tree?

EDIT (code solution):

Here is a solution based on ideas from Juan's response. I'm putting this up in case anyone finds this thread in the future and is looking for some code.

function getNodeList(bfsQueue) {
    var node = bfsQueue.pop();
    var nodeQueue = [];

    for (var ii = 0; ii < node.childNodes.length; ii++) {
        bfsQueue.push( node.childNodes[ii] );
        nodeQueue.push( node.childNodes[ii] );
    }
    if (bfsQueue.length === 0) {
        return nodeQueue;
    } else {
        return nodeQueue.concat( getNodeList(bfsQueue) );
    }
}

var startQueue = [];
var nodeList = [];

startQueue.push( tree.getRootNode() );
nodeList.push( tree.getRootNode() );
nodeList = nodeList.concat(getNodeList( startQueue ));
console.dir(nodeList);

for ( var nn = nodeList.length-1; nn >= 0; nn-- ) {

    var params = [];
    for (var pp in nodeList[nn].attributes) {
        if (pp === "children" || pp === "loader") {continue;}
        params.push('"' + pp + '":' + JSON.stringify(nodeList[nn].attributes[pp]) + '');
    }

    if ( nodeList[nn].childNodes.length > 0) {
        var childList = [];

        for (var ii = 0; ii < nodeList[nn].childNodes.length; ii++) {
            childList.push( nodeList[nn].childNodes[ii].json );
        }

        params.push('"children": [' + childList.join(',') + ']');
    }

    nodeList[nn].json = "{" + params.join(",") + "}";
}

console.log(nodeList[0].json); // root node
patorjk
  • 2,164
  • 1
  • 20
  • 30

4 Answers4

2

First of all, what you really want is the attributes property, which is the JSON used to create a node. Most relevant properties are updated, but childNodes is not. So you have to write something to put that back in.

By traversing the tree using childNodes, you can get all the nodes. You'll need to reassemble them back into a single json.

Ext.data.Node.prototype.getJson = function () {
      // Should deep copy so we don't affect the tree
      var json = this.attributes;

      json.children = [];
      for (var i=0; i < node.childNodes.length; i++) {
          json.children.push( node.childNodes[i].getJson() )
      }
      return json;
}

tree.getRootNode().getJson();

This example is not perfect, but should give you enough to get started.

Update

In Ext-JS 4.0 Nodes are now decorated into Records. Therefore, all the extra properties should be documented through the records/model interface and retrieved set using the get and set methods

Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
  • I didn't know about the attributes property. That and the childNodes array are just what I needed. Thank you for the info! – patorjk Dec 08 '10 at 23:03
  • @Stevanicus Thanks for the Ext-JS 4.0 update. Note that you should prefer setting a model definition and the `get/set` interface instead than accessing the `.data` property directly so that you're not working with undocumented properties – Ruan Mendes Mar 15 '13 at 15:54
0

In the latest ExtJS version the NodeInterface for Tree Nodes has an serialize function that does this. Maybe that is relevant for you.

htk
  • 1
0
getTreeObjectJSONData: function (objectPanel) {
    var objectStore = objectPanel.getStore(),
        dataCollection = [];
    if (objectStore.data.items !== undefined) {
        $.each(objectStore.data.items, function (index, objectData) {
            if (!objectData.data.leaf) {
                dataCollection['groups'].push({
                    display_name: objectData.data.name,
                    group: objectData.data.group,
                    crudState: objectData.data.crudState,
                    unique_id: objectData.data.unique_id
                });
            } else {
                dataCollection['fields'].push({
                    display_name: objectData.data.name,
                    group: objectData.data.group,
                    type: objectData.data.type != undefined ? objectData.data.type : 'null',
                    crudState: objectData.data.crudState,
                    unique_id: objectData.data.unique_id
                });
            }
        })

    }
    return Ext.util.JSON.encode(dataCollection);
}

Probably It'll be helpful

AgE
  • 387
  • 2
  • 8
0
var root = TreePanel.getRootNode();
var res = root.serialize();
console.log(res)
Ilyes
  • 41
  • 3
  • 1
    While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value. You can find more information on how to write good answers in the help center: https://stackoverflow.com/help/how-to-answer . Good luck – nima Oct 23 '21 at 10:20