简体   繁体   English

拖放代码适用于Ext JS 4.0.7,但不适用于更高版本

[英]Drag-drop code works on Ext JS 4.0.7 but not later versions

I'm quite new to Ext JS and I wanted to understand a bit more about how drag and drop works. 我是Ext JS的新手,我想进一步了解拖放的工作原理。 So I was looking at the article on http://www.codeslower.com/2011/7/Using-the-draggable-property-in-ExtJS . 因此,我正在看http://www.codeslower.com/2011/7/Using-the-draggable-property-in-ExtJS上的文章。 I wrote a JS Fiddle based on this which is at http://jsfiddle.net/F2xsM/ which uses Ext JS 4.0.7 as per the example. 我在http://jsfiddle.net/F2xsM/上基于此编写了一个JS Fiddle,根据示例使用了Ext JS 4.0.7。 If I swap in Ext JS 4.1.0 or later versions (eg JS Fiddle - http://jsfiddle.net/HpPhy/ with 4.2.0) the code doesn't work properly. 如果我交换了Ext JS 4.1.0或更高版本(例如JS Fiddle- http://jsfiddle.net/HpPhy/以及4.2.0),代码将无法正常工作。 Only the first drag works. 仅第一个拖动有效。 After that there's a load of errors in the console. 之后,控制台中将出现大量错误。

Here's the code: 这是代码:

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));
    };
}

What do I need to change to fix this? 我需要更改以解决此问题?


Update : I can see it's go tosmething to do with the ghost element and the line droppedPanel.destroy(); 更新 :我可以看到它与ghost元素和droppedPanel.destroy();droppedPanel.destroy();

Dropped panel is apparently used somewhere after notifyDrop (you can see in stack trace stopDrag method when exception is thrown). 显然,在notifyDrop之后的某个地方使用了notifyDrop面板(当引发异常时,您可以在堆栈跟踪stopDrag方法中看到)。

Easiest way to fix that is to delay destroy call or use endDrag callback: 解决此问题的最简单方法是延迟destroy调用或使用endDrag回调:

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

Working sample: http://jsfiddle.net/HpPhy/4/ 工作示例: http : //jsfiddle.net/HpPhy/4/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM