Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/474.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript dojo dijit/拖放树:如何区分移动和复制?_Javascript_Dojo - Fatal编程技术网

Javascript dojo dijit/拖放树:如何区分移动和复制?

Javascript dojo dijit/拖放树:如何区分移动和复制?,javascript,dojo,Javascript,Dojo,使用中的思想,我试图实现一个带有拖放的树 下面是我的树的简化版本。请注意,checkItemAcceptance()可以判断项目是否正在移动(未按ctrl键)或复制(按ctrl键)\ ed)。。。但是我不知道如何从aspect包装的put()方法中进行区分。有什么建议吗 <html> <head> <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/dojo/1.12.2/dojo/r

使用中的思想,我试图实现一个带有拖放的树

下面是我的树的简化版本。请注意,checkItemAcceptance()可以判断项目是否正在移动(未按ctrl键)或复制(按ctrl键)\ ed)。。。但是我不知道如何从aspect包装的put()方法中进行区分。有什么建议吗

<html>
<head>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/dojo/1.12.2/dojo/resources/dojo.css"/>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/dojo/1.12.2/dijit/themes/claro/claro.css"/>
</head>
<body class="claro">

<script src="https://ajax.googleapis.com/ajax/libs/dojo/1.12.2/dojo/dojo.js" data-dojo-config="async: true"></script>
<h1>Demo</h1>

<script type="text/javascript">
require(["dojo/dom","dojo/store/Observable","dojo/store/Memory","dojo/store/JsonRest","dijit/tree/ObjectStoreModel","dijit/Tree",
         "dojo/aspect","dijit/tree/dndSource","dijit/registry","dojo/domReady!"],
function(dom,Observable,Memory,JsonRest,ObjectStoreModel,Tree,aspect,dndSource,registry) {

    var jstore = new Memory({
        data:[
            {id:1,name:"/",          parent_id:null,item_type:"folder",rwx:5},
            {id:2,  name:"dir1",     parent_id:1,   item_type:"folder",rwx:7},
            {id:3,  name:"dir2",     parent_id:1,   item_type:"folder",rwx:7}, 
            {id:4,  name:"file1",    parent_id:3,   item_type:"file"  ,rwx:7},  
            {id:5,  name:"file2",    parent_id:3,   item_type:"file"  ,rwx:7},
        ],
        getChildren: function(obj) {
            return this.query({parent_id:obj.id});
        }
    });

    aspect.around(jstore,"put",function(originalPut) {
        return function(obj,options) {
            console.log("store.put("+JSON.stringify(obj)+","+JSON.stringify(options));
            if (options && options.parent) {
                obj.parent_id = options.parent.id;
            }
            return originalPut.call(jstore,obj,options);
        };
    });
    var store = new Observable(jstore);

    var myModel = new ObjectStoreModel({
        store: store,
        query: {id:1}
    });
    myModel.getLabel = function(item) {
        return JSON.stringify(item);
    };
    myModel.mayHaveChildren = function(item) {
        return item.item_type == 'folder';
    };

    var tree = new Tree({
        model: myModel,
        getIconClass: function(item,opened) {
            console.log("tree.getIconClass: " + JSON.stringify(item));
            return (item.item_type == 'folder') ? ( opened ? "dijitFolderOpened" : "dijitFolderClosed" ) : 'dijitLeaf';
        }
    });
    var mydnd = new dndSource(tree,{
        checkItemAcceptance: function(target,source,position) {
            var targetItem = registry.byNode(target.parentNode).item;
            var sourceItems = registry.byNode(source.node).selectedItems;
            if (targetItem.item_type != 'folder') {
                console.log("checkItemAcceptance; dest is not a folder: "+source.sourceState+" items "+JSON.stringify(sourceItems)+" to "+JSON.stringify(targetItem));
                return 0;
            }
            if (!(targetItem.rwx & 2)) {
                console.log("checkItemAcceptance; can't create in dest: "+source.sourceState+" items "+JSON.stringify(sourceItems)+" to "+JSON.stringify(targetItem));
                return 0;
            }
            for (var i=0; i < sourceItems.length; ++i) {
                x = sourceItems[i];
                if (x.parent_id == targetItem.id) {
                    console.log("checkItemAcceptance; same directory: "+source.sourceState+" items "+JSON.stringify(sourceItems)+" to "+JSON.stringify(targetItem));
                    return 0;
                }
                if (!(x.rwx & 4)) {
                    console.log("checkItemAcceptance; item not readable: "+source.sourceState+" items "+JSON.stringify(sourceItems)+" to "+JSON.stringify(targetItem));
                    return 0;
                }
                if (source.sourceState == 'Moved') { // as opposed to 'Copied'
                    var parentItem = registry.byNode(registry.byNode(source.node).selectedNodes[0].domNode.parentNode.parentNode).item;
                    //console.log("checkItemAcceptance: parentItem is " + JSON.stringify(parentItem));
                    if (!(parentItem.rwx & 2)) {
                        console.log("checkItemAcceptance; from folder doesn't allow delete: "+source.sourceState+" items "+JSON.stringify(sourceItems)+" to "+JSON.stringify(targetItem));
                        return 0;
                    }
                }
            };
            return 1;
        }
    });
    tree.dndController = mydnd;
    tree.placeAt(dom.byId("treePlaceholder"));
    tree.startup();
});

</script>

<div id="treePlaceholder"/>
</body>
</html>

演示
require([“dojo/dom”、“dojo/store/Observable”、“dojo/store/Memory”、“dojo/store/JsonRest”、“dijit/tree/ObjectStoreModel”、“dijit/tree”,
“dojo/aspect”、“dijit/tree/dndSource”、“dijit/registry”、“dojo/domReady!”],
函数(dom、可观察、内存、JsonRest、ObjectStoreModel、树、方面、dndSource、注册表){
var jstore=新内存({
数据:[
{id:1,名称:“/”,父项id:null,项类型:“文件夹”,rwx:5},
{id:2,名称:“dir1”,父\u id:1,项类型:“文件夹”,rwx:7},
{id:3,名称:“dir2”,父\u id:1,项类型:“文件夹”,rwx:7},
{id:4,名称:“file1”,父项id:3,项类型:“file”,rwx:7},
{id:5,名称:“file2”,父项id:3,项类型:“file”,rwx:7},
],
getChildren:函数(obj){
返回这个.query({parent_id:obj.id});
}
});
aspect.around(jstore,“put”,函数(originalPut){
返回功能(obj,选项){
log(“store.put”(“+JSON.stringify(obj)+”,“+JSON.stringify(options));
if(options&&options.parent){
obj.parent_id=options.parent.id;
}
返回originalPut.call(jstore、obj、options);
};
});
var store=新的可观测值(jstore);
var myModel=新的ObjectStoreModel({
店:店,,
查询:{id:1}
});
myModel.getLabel=函数(项){
返回JSON.stringify(item);
};
myModel.mayHaveChildren=函数(项){
return item.item_type=='folder';
};
var-tree=新树({
型号:myModel,
getIconClass:函数(项,已打开){
log(“tree.getIconClass:+JSON.stringify(item));
返回(item.item_type=='folder')?(打开?“DijitFolderOpen”:“dijitFolderClosed”):'dijitLeaf';
}
});
var mydnd=新的dndSource(树{
checkItemAcceptance:功能(目标、来源、位置){
var targetItem=registry.byNode(target.parentNode).item;
var sourceItems=registry.byNode(source.node);
如果(targetItem.item_type!=“文件夹”){
log(“checkItemAcceptance;dest不是文件夹:“+source.sourceState+”items”+JSON.stringify(sourceItems)+”到“+JSON.stringify(targetItem));
返回0;
}
如果(!(targetItem.rwx&2)){
log(“checkItemAcceptance;无法在dest中创建:“+source.sourceState+”items”+JSON.stringify(sourceItems)+”到“+JSON.stringify(targetItem));
返回0;
}
对于(变量i=0;i
您不必用自己的代码区分移动和复制;dojo dnd模块和dijit树已经实现了这种逻辑。但是,您需要一个本机支持put()方法并可以在层次结构中定位项的存储区。MemoryStore不支持这一点以及围绕put()的方面只是一个简单的例子。一个有效的存储是ItemFileWriteStore。这有一个带有ItemFileWriteStore的树的例子。

我的解决方案,我认为,只是有点难看;它涉及覆盖ObjectStoreModel的pasteItem()方法,将新属性“isCopy”添加到它传递给存储的put()的选项中方法。下面是我修改过的示例,演示了这一点:

<html>
<head>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/dojo/1.12.2/dojo/resources/dojo.css"/>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/dojo/1.12.2/dijit/themes/claro/claro.css"/>
</head>
<body class="claro">

<script src="https://ajax.googleapis.com/ajax/libs/dojo/1.12.2/dojo/dojo.js" data-dojo-config="async: true"></script>
<h1>Demo</h1>

<script type="text/javascript">
require(["dojo/dom","dojo/store/Observable","dojo/store/Memory","dojo/store/JsonRest","dijit/tree/ObjectStoreModel","dijit/Tree",
         "dojo/aspect","dijit/tree/dndSource","dijit/registry","dojo/Deferred","dojo/_base/lang","dojo/_base/array","dojo/domReady!"],
function(dom,Observable,Memory,JsonRest,ObjectStoreModel,Tree,aspect,dndSource,registry,Deferred,lang,array) {

    var jstore = new Memory({
        data:[
            {id:1,name:"/",          parent_id:null,item_type:"folder",rwx:5},
            {id:2,  name:"dir1",     parent_id:1,   item_type:"folder",rwx:7},
            {id:3,  name:"dir2",     parent_id:1,   item_type:"folder",rwx:7}, 
            {id:4,  name:"file1",    parent_id:3,   item_type:"file"  ,rwx:7},  
            {id:5,  name:"file2",    parent_id:3,   item_type:"file"  ,rwx:7},
        ],
        getChildren: function(obj) {
            return this.query({parent_id:obj.id});
        }
    });

    aspect.around(jstore,"put",function(originalPut) {
        return function(obj,options) {
            console.log("store.put("+JSON.stringify(obj)+","+JSON.stringify(options));
            if (options && options.parent) {
                obj.parent_id = options.parent.id;
            }
            return originalPut.call(jstore,obj,options);
        };
    });
    var store = new Observable(jstore);

    var myModel = new ObjectStoreModel({
        store: store,
        query: {id:1},
        // A modified copy of dojo 1.10.0's dijit/tree/ObjectStoreModel.js's
        pasteItem:  function(/*Item*/ childItem, /*Item*/ oldParentItem, /*Item*/ newParentItem,
                                    /*Boolean*/ bCopy, /*int?*/ insertIndex, /*Item*/ before){
                    // summary:                                                                                                                                                     
                    //              Move or copy an item from one parent item to another.                                                                                           
                    //              Used in drag & drop.                                                                                                                            

                    var d = new Deferred();

                    if(oldParentItem === newParentItem && !bCopy && !before){
                            // Avoid problem when items visually disappear when dropped onto their parent.                                                                          
                            // Happens because the (no-op) store.put() call doesn't generate any notification                                                                       
                            // that the childItem was added/moved.                                                                                                                  
                            d.resolve(true);
                            return d;
                    }

                    if(oldParentItem && !bCopy){
                            // In order for DnD moves to work correctly, childItem needs to be orphaned from oldParentItem                                                          
                            // before being adopted by newParentItem.   That way, the TreeNode is moved rather than                                                                 
                            // an additional TreeNode being created, and the old TreeNode subsequently being deleted.                                                               
                            // The latter loses information such as selection and opened/closed children TreeNodes.                                                                 
                            // Unfortunately simply calling this.store.put() will send notifications in a random order, based                                                       
                            // on when the TreeNodes in question originally appeared, and not based on the drag-from                                                                
                            // TreeNode vs. the drop-onto TreeNode.                                                                                                                 

                            this.getChildren(oldParentItem, lang.hitch(this, function(oldParentChildren){
                                    oldParentChildren = [].concat(oldParentChildren); // concat to make copy                                                                        
                                    var index = array.indexOf(oldParentChildren, childItem);
                                    oldParentChildren.splice(index, 1);
                                    this.onChildrenChange(oldParentItem, oldParentChildren);

                                    d.resolve(this.store.put(childItem, {
                                            overwrite: true,
                                            parent: newParentItem,
                                            oldParent: oldParentItem,
                                            before: before,
                                            isCopy: false
                                    }));
                            }));
                    }else{
                            d.resolve(this.store.put(childItem, {
                                    overwrite: true,
                                    parent: newParentItem,
                                    oldParent: oldParentItem,
                                    before: before,
                                    isCopy: true
                            }));
                    }

                    return d;
            },
    });

    myModel.getLabel = function(item) {
        return JSON.stringify(item);
    };
    myModel.mayHaveChildren = function(item) {
        return item.item_type == 'folder';
    };

    var tree = new Tree({
        model: myModel,
        getIconClass: function(item,opened) {
            console.log("tree.getIconClass: " + JSON.stringify(item));
            return (item.item_type == 'folder') ? ( opened ? "dijitFolderOpened" : "dijitFolderClosed" ) : 'dijitLeaf';
        }
    });
    var mydnd = new dndSource(tree,{
        checkItemAcceptance: function(target,source,position) {
            var targetItem = registry.byNode(target.parentNode).item;
            var sourceItems = registry.byNode(source.node).selectedItems;
            if (targetItem.item_type != 'folder') {
                console.log("checkItemAcceptance; dest is not a folder: "+source.sourceState+" items "+JSON.stringify(sourceItems)+" to "+JSON.stringify(targetItem));
                return 0;
            }
            if (!(targetItem.rwx & 2)) {
                console.log("checkItemAcceptance; can't create in dest: "+source.sourceState+" items "+JSON.stringify(sourceItems)+" to "+JSON.stringify(targetItem));
                return 0;
            }
            for (var i=0; i < sourceItems.length; ++i) {
                x = sourceItems[i];
                if (x.parent_id == targetItem.id) {
                    console.log("checkItemAcceptance; same directory: "+source.sourceState+" items "+JSON.stringify(sourceItems)+" to "+JSON.stringify(targetItem));
                    return 0;
                }
                if (!(x.rwx & 4)) {
                    console.log("checkItemAcceptance; item not readable: "+source.sourceState+" items "+JSON.stringify(sourceItems)+" to "+JSON.stringify(targetItem));
                    return 0;
                }
                if (source.sourceState == 'Moved') { // as opposed to 'Copied'
                    var parentItem = registry.byNode(registry.byNode(source.node).selectedNodes[0].domNode.parentNode.parentNode).item;
                    //console.log("checkItemAcceptance: parentItem is " + JSON.stringify(parentItem));
                    if (!(parentItem.rwx & 2)) {
                        console.log("checkItemAcceptance; from folder doesn't allow delete: "+source.sourceState+" items "+JSON.stringify(sourceItems)+" to "+JSON.stringify(targetItem));
                        return 0;
                    }
                }
            };
            return 1;
        }
    });
    tree.dndController = mydnd;
    tree.placeAt(dom.byId("treePlaceholder"));
    tree.startup();
});

</script>

<div id="treePlaceholder"/>
</body>
</html>

演示
require([“dojo/dom”、“dojo/store/Observable”、“dojo/store/Memory”、“dojo/store/JsonRest”、“dijit/tree/ObjectStoreModel”、“dijit/tree”,
“dojo/aspect”、“dijit/tree/dndSource”、“dijit/registry”、“dojo/Deferred”、“dojo/_base/lang”、“dojo/_base/array”、“dojo/domReady!”],
函数(dom、Observable、Memory、JsonRest、ObjectStoreModel、Tree、aspect、DnsSource、registry、Delived、lang、array){
var jstore=新内存({
数据:[
{id:1,名称:“/”,父项id:null,项类型:“文件夹”,rwx:5},
{id:2,名称:“dir1”,父\u id:1,项类型:“文件夹”,rwx:7},
{id:3,名称:“dir2”,父\u id:1,项类型:“文件夹”,rwx:7},
{id:4,名称:“file1”,父项id:3,项类型:“file”,rwx:7},
{id:5,名称:“文件2”,父项id:3,项类型:“f”