无法将ExtJS 4.0.7树节点拖到面板并接收notifyDrop事件

时间:2014-01-28 18:09:42

标签: extjs extjs4

我有一个简单的布局,左边是Ext.tree.Panel,右边是Ext.panel.Panel。右侧面板的内容旨在成为d3可视化。

树面板定义为:

Ext.define('MyTreeModel', {
  extend: 'Ext.data.Model',
  fields: [
    { name: 'id', type: 'string' }, 
    { name: 'text', type: 'string' },
    { name: 'ddGroup', type: 'string', defaultValue: 'myDropGroup' },
    { name: 'draggable', type: 'boolean', defaultValue: true }
  ]
});

var myStore = Ext.create('Ext.data.TreeStore', {
  model: 'myTreeModel',
  autoSync: true,
  autoLoad: true,
  proxy: {
    type: 'ajax',
    url: 'myendpoint.json',
    reader: { type: 'json' }
  }
});

Ext.define('MyTreePanel', {
  extend: 'Ext.tree.Panel',
  alias: 'widget.mytreepanel',
  enableDD: true,                // not sure if this is necessary
  ddGroup: 'myDropGroup',        //             "
  rootVisible: false,
  store: myStore
}

应该接收放置事件的面板定义为:

Ext.define('MyDropPanel', {
  extend: 'Ext.panel.Panel',
  items: [
    {
      xtype: 'component',
      id: 'd3Component',
      autoEl: { tag: 'div' }
    }
  ],
  ddGroup: 'myDropGroup',      // not sure if this is necessary
  enableDD: true,              //           "
  listeners: {
    render: initializeDropTarget,
    afterLayout: buildInitialD3Visualization // here's where the d3 SVG gets set up
  }
});

function initializeDropTarget(panel) {
  panel.dropTarget = Ext.dd.DropTarget.create(panel.el, {
    ddGroup: 'myDropGroup',
    notifyDrop: function(dd, e, data) {
      console.log("something dropped!");  // so far I have not seen this method fire.
    }
  });
}

我是ExtJS的新手,但这些都是我尝试过的东西:

  1. 我尝试使用插件treeviewdragdrop。这允许在树中拖放,但是对于我的面板是否收到掉落事件没有影响。
  2. 我尝试添加enableDD属性,但实际上它似乎不是ExtJS 4 Panel类的已定义属性。到目前为止它似乎没有帮助。
  3. 我想知道是否存在“简单”div(可视化显示的位置)是导致问题的原因吗?

1 个答案:

答案 0 :(得分:3)

对于ExtJS中的拖放操作,您需要配置拖动源和放置目标。

拖动源

如何将树设置为dragSource的最简单方法是使用Ext.tree.plugin.TreeViewDragDrop插件。在此插件的配置中,您应设置dragGroup的名称。通过此标识符,您可以将dragSourcedropTarget绑定在一起。

var tree = Ext.create('Ext.tree.Panel', {
    title: 'Simple Tree',
    width: 400,
    height: 600,
    store: store,
    rootVisible: false,            
    viewConfig: {
        plugins: {
            ptype: 'treeviewdragdrop',
            copy: true,
            dragGroup: 'myDDGroup'
        }
    },
});

放弃目标

然后您需要在dropTarget上创建Ext.panel.Panel。为此,您可以使用Ext.dd.DropTarget。此类实现了一些可以覆盖并用于处理拖放事件的通知方法。

当拖动的元素被放置在目标上时,将调用notifyDrop方法。如果此方法返回true,则认为drop是成功的。

因为您使用dragSource treeviewdragdrop,每个通知方法的data参数还包含属于拖动树节点(data.records)的记录数组。

您可以定义自己的扩展Ext.dd.DropTarget的类:

Ext.define('myPanelDropTarget', {
    extend: 'Ext.dd.DropTarget',

    notifyEnter : function(source, e, data) {
        console.log('enter');
        return this.callParent(arguments);
    },                
    notifyOut : function(source, e, data) {
        console.log('out');
        return this.callParent(arguments);
    },

    notifyOver : function(source, e, data) {
        console.log('over');
        return this.callParent(arguments);
    },                
    notifyDrop : function(source, e, data) {
        var me = this;
        console.log('drop');

        var text = data.records[0].get('text');

        var d3ComponentEl = me.panel.down('#d3Component').getEl();

        d3ComponentEl.insertHtml('beforeEnd', text + '<br />');                

        return true;
    }                           
});

配置了放置目标的面板

最后,您可以将面板设置为dropTargetdropTarget将在afterrender事件处理程序中创建,因为您需要将其绑定到面板DOM元素(并且此元素仅在呈现面板后存在)。此外,您必须使用与dropTarget插件配置中使用的ddGroup名称相同的treeviewdragdrop进行配置:

var panel = Ext.create('Ext.panel.Panel', {
    title: 'Drop Target Panel',
    border: true,
    width: 400,
    height: 600,
    items: [
        {
          xtype: 'component',
          id: 'd3Component',
          autoEl: { tag: 'div' }
        }
    ],
    listeners: {
        'afterrender': function () {
            panel.dropZone = Ext.create('myPanelDropTarget', panel.getEl(), {
                ddGroup: 'myDDGroup',
                panel: panel
            });                    
        }
    }            
});

我还将面板实例传递给myPanelDropTarget对象,因为例如我将删除的节点名称添加到面板内容中。

实施例

完整的实例: https://fiddle.sencha.com/#fiddle/340