开发者

How do I get rid of recursive AJAX requests for a childless node?

Problem:

According to the author, jsTree Documentation:

When opening a closed node (that has no loaded children) an AJAX request is made.

How do I configure jsTree to get rid of these AJAX data requests made for each empty/childless node? I want my empty nodes remain empty (or childless)!


Given (simplified):

JSON data container (data.json)

{
    "data" : "Root node with no ch开发者_运维技巧ildren",
    "children" : []
}

jsTree configuration

{
    "json_data" : {
        "ajax" : {
            "url"        : "data.json",
            "type"       : "GET",
            "dataType"   : "json",
            "dataFilter" : function (data, type) {
                //some filtering function
            }
        }
    },
    "plugin" : ["json_data"]
}


Mark the state of the leaf node as "leaf". That should fix it.


I have had this problem setting the attribute state="closed" on childless nodes for XML trees. Removing the state attribute solves the issue.


I had a similar problem a couple of weeks ago. I had a function call in the "url" field, which ultimately led to java code that made a JSON string based on a SQL query. So when I clicked on a childless closed node, the function was called again, resulting in an endless tree.

the way I solved this was:

"json_data" : {
        "ajax" : {
            "url" : "getAreaTree?treeType=Areas&ownerPhone=<%=webSessionObject.getUserPhoneNum()%>",
            "data" : function (n) {
                    return { id : n.attr ? n.attr("id") : 0 };
                }
        }
    },

The result of the function defined in "data" will be added as a parameter to the "url" function. Then I can check whether the parameter was 0 (initial load) or 1 (the id of my root) or something else.

If this doesn't work for you, maybe you could try something like this:

.bind("before.jstree",function(event,data){
    if(data.func === "create"){
                  var foo = true;
        data.inst._get_node(null, true).each(function () {

            if(this.id!=rootId && this.id!=0){
                foo = false;    
        })
        if(!foo){
            event.stopImmediatePropagation();
            return false;
        }
    }       
})

I'm not exactly sure this works though. "before.jstree" fires before all events. I'm checking whether the function about to fire is "create", and if it is I check the id of the selected node. If it's something else than my root's id or 0 (initial load) I stop the create function.

I use a similar structure for a different situation, so something like this should work. It could be that the "create" event is not what you should be binding to though. You can change it to

.bind("before.jstree",function(event,data){
            console.log(data.func)
    if(data.func === "create"){

To see which functions are called.


Just skip the children attribute. Obviously your node has no children, but you specify the attribute? Simply skip it, the node will be rendered as a leaf node and no further requests will be made.


I've been struggling with this problem too. I got the main idea from jsTree - loading subnodes via ajax on demand

The basic problem is that when we click a child node that is not set to leaf, a new AJAX request is generated with the URL we set in the tree configuration. The trick seen in the above link is to provide a function instead of a static URL string. My jstree is used to display a directory structure on the server, so I can arrange to dynamically add to the URL for sub-directories. If you assign a function to the url property of the ajax property in your jstree configuration, the function receives the node you clicked as an argument. My nodes display the names of directories or files so I can use the text() function to get the raw directory name. There seems to be some space in front of the name returned in this way, so I used a String trim() function and then encodeURIComponent to give me something I can use in a URL.

If -1 is passed to the url function, then you're at the root and you can safely use your base URL. Now, this only works for the first level of the hierarchy. I've got a bit more work to do, adding the full path to the metadata of the node or something like that, but this idea might put you on the right track. It looks as if it's not exactly a bug but by design. You have to make sure a request triggered by a subnode sends a suitable URL to the server.

Here's the url property I've assigned to the ajax object in my jstree configuration:

"url": function (node) {
    var subDirectory = "",
    url = "";
    if (node === -1)
    {
        url = "/tree_service/tree/format/json?path=exercises";
    }
    else
    {
        subDirectory = encodeURIComponent(node.text().trim());
        url = "/tree_service/tree/format/json?path=exercises/" + subDirectory;
    }
    return url;
}

My plan is to build the URL cumulatively by polling the node for its full path, then adding the node's name as above to create the final URL. Pseudo code:

//haven't figured out how to add the path to the node and then retrieve it
path = node.metadata.path;
path = encodeURIComponent(path);
subDirectory = encodeURIComponent(node.text().trim());
url = path + "/" + subDirectory;

UPDATE See my answer here how to get the metadata of jsTree. about getting the metadata from the node using node.data().path

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜