Dojo扩展了dojo.dnd.Source,移动没有发生。想法?

时间:2010-06-10 00:57:20

标签: javascript drag-and-drop dojo

通知:这已经解决了,我会尽快在这里发布解决方案。

嘿所有,

好的......我有一个简单的dojo页面,其中包含基本要素。三个UL,里面有一些LI。想法允许它们之间的拖放,但如果任何UL由于最后一项被拖出而变空,我会向用户发出一条消息,告诉他们一些指示。

为了做到这一点,我想扩展dojo.dnd.Source dijit并添加一些智能。这似乎很容易。为了简单起见(我从CDN加载Dojo)我只是简化扩展而不是在模块加载上完成。声明功能在这里......

function declare_mockupSmartDndUl(){
dojo.require("dojo.dnd.Source");
dojo.provide("mockup.SmartDndUl");
dojo.declare("mockup.SmartDndUl", dojo.dnd.Source, {
    markupFactory: function(params, node){
        //params._skipStartup = true;
        return new mockup.SmartDndUl(node, params);
    },
    onDndDrop: function(source, nodes, copy){
        console.debug('onDndDrop!');    
        if(this == source){
            // reordering items
            console.debug('moving items from us');
            // DO SOMETHING HERE
        }else{
            // moving items to us
            console.debug('moving items to us');
            // DO SOMETHING HERE
        }

        console.debug('this = ' + this );
        console.debug('source = ' + source );   
        console.debug('nodes = ' + nodes);
        console.debug('copy = ' + copy);
        return dojo.dnd.Source.prototype.onDndDrop.call(this, source, nodes, copy);
    }   
});
}

我有一个init函数来使用它来装饰列表......

dojo.addOnLoad(function(){
declare_mockupSmartDndUl();
if(dojo.byId('list1')){
    //new mockup.SmartDndUl(dojo.byId('list1'));
    new dojo.dnd.Source(dojo.byId('list1'));
}

if(dojo.byId('list2')){
    new mockup.SmartDndUl(dojo.byId('list2'));
    //new dojo.dnd.Source(dojo.byId('list2'));
}

if(dojo.byId('list3')){
    new mockup.SmartDndUl(dojo.byId('list3'));
    //new dojo.dnd.Source(dojo.byId('list3'));
}
});

尽管它很好,你会发现我把“list1”作为标准的dojo dnd源进行测试。

问题是这样的 - list1会很乐意接受来自列表2&的项目。 3谁将移动或复制为适当的。然而,列表2& 3拒绝接受list1中的项目。好像DND操作被取消了,但是调试器确实显示了dojo.dnd.Source.prototype.onDndDrop.call正在发生,并且参数者看起来对我好。

现在,这里的文档非常薄弱,所以我从中获取的一些示例可能已经过时了(我使用的是1.4)。

任何人都可以填写我的扩展程序dijit可能存在的问题吗?

谢谢!

3 个答案:

答案 0 :(得分:1)

如果使用Dojo XD加载程序(与CDN一起使用),则所有dojo.require()都是异步的。然而,declare_mockupSmartDndUl()假设只要它dojo.dnd.Source它就可用。一般情况下不保证。

另一个挑剔:dojo.dnd.Source不是widget / dijit,虽然它是可编写脚本的并且可以与Dojo Markup一起使用,但它不会实现任何Dijit的接口。

现在问题 - 你要覆盖的方法在1.4中有以下定义:

onDndDrop: function(source, nodes, copy, target){
    // summary:
    //      topic event processor for /dnd/drop, called to finish the DnD operation
    // source: Object
    //      the source which provides items
    // nodes: Array
    //      the list of transferred items
    // copy: Boolean
    //      copy items, if true, move items otherwise
    // target: Object
    //      the target which accepts items
    if(this == target){
        // this one is for us => move nodes!
        this.onDrop(source, nodes, copy);
    }
    this.onDndCancel();
},

请注意,它有4个参数,而不是3.正如您所看到的,如果您没有传递4 th 参数,则onDrop永远不会被父方法调用。

解决这两个问题,很可能你会得到你想要的东西。

答案 1 :(得分:0)

最后,我点击了Dojo IRC(伟大的人们!)然后我们最终(到目前为止)了...

    function declare_mockupSmartDndUl(){
    dojo.require("dojo.dnd.Source");
    dojo.provide("mockup.SmartDndUl");
    dojo.declare("mockup.SmartDndUl", dojo.dnd.Source, {
        markupFactory: function(params, node){
            //params._skipStartup = true;
            return new mockup.SmartDndUl(node, params);
        },
        onDropExternal: function(source, nodes, copy){
            console.debug('onDropExternal called...');  

            // dojo.destroy(this.getAllNodes().query(".dndInstructions"));
            this.inherited(arguments);

            var x = source.getAllNodes().length;
            if( x == 0 ){
                newnode = document.createElement('li');
                newnode.innerHTML = "You can drag stuff here!";
                dojo.addClass(newnode,"dndInstructions");
                source.node.appendChild(newnode);
            }

            return true;
            // return dojo.dnd.Source.prototype.onDropExternal.call(this, source, nodes, copy);
        }   
    });
}

你可以看到我正在前进的地方,当源是空的时我输入了一条消息(客户端规格,ug!)我需要找到一种方法来杀死它(因为它不是,按照定义,在任何阻碍下拖空!)。那部分工作得很好。

无论如何,魔术不是使用onDnd_____函数,而是使用更高级别的函数,然后调用this.inherited(arguments)来启动内置函数。

谢谢!

答案 2 :(得分:0)

dojo.require("dojo.dnd.Source");
dojo.provide("mockup.SmartDndUl");
dojo.declare("mockup.SmartDndUl", dojo.dnd.Source, {

Dojo require语句和声明语句紧挨着下一个。我认为这会导致依赖性问题。

dojo require语句应该在onload块之外,而declare语句应该在onload块中。