0

我对 Ext JS 很陌生,我想更多地了解拖放是如何工作的。所以我在看 http://www.codeslower.com/2011/7/Using-the-draggable-property-in-ExtJS上的文章。我基于此编写了一个 JS Fiddle,它位于http://jsfiddle.net/F2xsM/,它根据示例使用 Ext JS 4.0.7。如果我换入 Ext JS 4.1.0 或更高版本(例如 JS Fiddle - http://jsfiddle.net/HpPhy/与 4.2.0),代码将无法正常工作。只有第一次拖动有效。之后,控制台中出现大量错误。

这是代码:

Ext.onReady(function() {
    Ext.create('Ext.container.Viewport', {
        layout: 'vbox',
        items: [{
            xtype: 'panel',
            title: 'Drop a Panel Here',
            listeners: { render: initializeDropTarget },
            cls: 'x-dd-drop-ok',
            layout: {
                type: 'vbox',
                stretch: 'align'
            },
            width: 300,
            height: 300
        }, {
            xtype: 'panel',
            title: 'Drag This Panel',
            draggable: true,
            bodyCls: 'green-body',
            width: 300,
            height: 100
        }, {
            xtype: 'panel',
            title: 'Drag This Panel',
            draggable: true,
            bodyCls: 'blue-body',
            width: 300,
            height: 100
        }, {
            xtype: 'panel',
            title: 'Drag This Panel',
            draggable: true,
            bodyCls: 'red-body',
            width: 300,
            height: 100
        }]
    });
});

/**
 Initialize the DropTarget object associated
 with our panel. The 'cmp' argument will be
 the panel (a Component object).
 */
function initializeDropTarget(targetPanel) {
    // Create the DropTarget object and assign it to the panel. Does not
    // have to be assigned to the panel but needs to be assigned to something,
    // or it will get garbage-collected too soon.
    targetPanel.dropTarget = Ext.create('Ext.dd.DropTarget', targetPanel.el);

    // Called once, when dragged item is dropped in the target area. Return false
    // to indicate an invalid drop. DO NOT MODIFY the UI in
    // this function. Use afterDragDrop and the data object.
    targetPanel.dropTarget.notifyDrop = function(source, evt, data) {
        if(typeof console != "undefined")
            console.log("notifyDrop:" + source.id);

        // The component that was dropped.
        var droppedPanel = Ext.getCmp(source.id);

        // We can't modify the component that was dropped in this
        // function. However, we can add an event handler on the component
        // that will be called shortly.
        //
        // In the handler we clone the component (not strictly necessary, we could
        // do that here) and then remove our old component.
        droppedPanel.dd.afterValidDrop = function() {
            targetPanel.add(droppedPanel.cloneConfig({
                draggable: false,
                title: "Can't Drag This Panel."
            }));

            droppedPanel.destroy();
        };

        return true;
    };

    // Called once, when dragged item enters drop area.
    targetPanel.dropTarget.notifyEnter = function(source, evt, data) {
        if(typeof console != "undefined")
            console.log("notifyEnter:" + source.id);

        return this.callParent(Array.prototype.slice.call(arguments));
    };

    // Called once, when dragged item leaves drop area.
    targetPanel.dropTarget.notifyOut = function(source, evt, data) {
        if(typeof console != "undefined")
            console.log("notifyOut:" + source.id);

        return this.callParent(Array.prototype.slice.call(arguments));
    };

    // Called for each mouse movement as dragged item is over the drop area.
    targetPanel.dropTarget.notifyOver = function(source, evt, data) {
        if(typeof console != "undefined")
            console.log("notifyOver:" + source.id);

        return this.callParent(Array.prototype.slice.call(arguments));
    };
}

我需要改变什么来解决这个问题?


更新:我可以看到它与幽灵元素和线条有关droppedPanel.destroy();

4

1 回答 1

0

被丢弃的面板显然在之后的某个地方使用(当抛出异常时notifyDrop,您可以在堆栈跟踪方法中看到)。stopDrag

解决这个问题的最简单方法是延迟destroy调用或使用endDrag回调:

droppedPanel.dd.endDrag = function() {
    droppedPanel.destroy();
};

工作样本:http: //jsfiddle.net/HpPhy/4/

于 2013-10-30T15:10:13.410 回答