【问题标题】:jstree dnd plugin - prevent move after drop?jstree dnd插件 - 防止掉落后移动?
【发布时间】:2018-06-08 23:21:52
【问题描述】:

用户使用 dnd 插件在 jsTree 中移动节点后,我需要执行 ajax 调用。如果该 ajax 调用返回错误,我需要阻止移动发生,或者完全反转操作。从move_node 事件侦听器中,有没有办法告诉 dnd 插件反转丢弃或以某种方式取消操作?我尝试返回 false 并设置 e.preventDefault()e.stopImmediatePropagation() 但似乎没有任何效果。

$($tree).jstree({
    core: {
        data: $treeData,
        check_callback: function (op, node, parent, position, more) {
            switch (op) {
                case 'move_node':
                    // moveNode() validates the move based on
                    // some data stored in each node, but doesn't
                    // (and shouldn't) make an ajax call to determine
                    // if the node *actually can* be moved
                    return moveNode(node, parent, position, more);
            }
        }
    },
    plugins: ['dnd']
}).on('move_node.jstree', function(e, data) {
    // moveNode() returned true and the user moved the node
    if (!doMoveNode(data)) {
        // none of this works!!
        e.preventDefault();
        e.stopImmediatePropagation();
        return false;
    }
});

【问题讨论】:

    标签: jstree jstree-dnd


    【解决方案1】:

    我想通了...关键是在动作发生之前拦截它,这可以在check_callback中完成,如下所示:

    function doMoveNode (node, parent) {
    
        // tell the server to move the node
    
        var nodeID = node.original.appData.id,
            parentID = parent.original.appData.id,
            success = false;
    
        // make a non-async call to move the node
    
        $.ajax({
            url: move-product.php',
            type: 'post',
            async: false,
            data: {
                nodeID: nodeID,
                parentID: parentID
            },
            dataType: 'json',
            success: function (json) {
                if (json.errorCode === 0) {
                    // this happens when the server was happy
                    success = true;
                }
            },
            error: function (xhr) {
                alert('an error occurred');
            }
        });
    
        return success;
    }
    
    function moveNode (node, parent, position, more) {
        // perform client-side validation to see if we can move node into parent
        // just a demo, so always return true
        return true;
    }
    
    $($tree).jstree({
        core: {
            data: $treeData,
            check_callback: function (op, node, parent, position, more) {
                switch (op) {
                    case 'move_node':
                        if (more && more.core) {
                            // this is the condition when the user dropped
                            // make a synchronous call to the server and
                            // return false if the server rejects the action
                            return doMoveNode(node, parent);
                        }
                        // return true if we can move, false if not
                        return moveNode(node, parent, position, more);
                }
            }
        },
        plugins: ['dnd']
    }).on('move_node.jstree', function(e, data) {
        // the move already happened
    });
    

    【讨论】: