我有一个简单的布局,左边是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的新手,但这些都是我尝试过的东西:
treeviewdragdrop
。这允许在树中拖放,但是对于我的面板是否收到掉落事件没有影响。enableDD
属性,但实际上它似乎不是ExtJS 4 Panel
类的已定义属性。到目前为止它似乎没有帮助。我想知道是否存在“简单”div(可视化显示的位置)是导致问题的原因吗?
答案 0 :(得分:3)
对于ExtJS中的拖放操作,您需要配置拖动源和放置目标。
如何将树设置为dragSource
的最简单方法是使用Ext.tree.plugin.TreeViewDragDrop
插件。在此插件的配置中,您应设置dragGroup
的名称。通过此标识符,您可以将dragSource
和dropTarget
绑定在一起。
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;
}
});
最后,您可以将面板设置为dropTarget
。 dropTarget
将在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
对象,因为例如我将删除的节点名称添加到面板内容中。