重新排序树时超出了ExtJS最大调用堆栈大小
我正在通过拖放重新排列树的层次结构。移动多个节点后,我得到错误重新排序树时超出了ExtJS最大调用堆栈大小,extjs,drag-and-drop,Extjs,Drag And Drop,我正在通过拖放重新排列树的层次结构。移动多个节点后,我得到错误uncaughtrangeerror:超过了最大调用堆栈大小。错误出现在NodeInterface.js中。updateInfo函数在以下行中崩溃 for(i=0;i
uncaughtrangeerror:超过了最大调用堆栈大小
。错误出现在NodeInterface.js
中。updateInfo
函数在以下行中崩溃
for(i=0;i
什么会导致这个问题
下面的代码显示了我如何在ExtJS 6.5.2中实现拖放和重新排序。也许你能找到问题的原因
插件
Ext.define('test.component.plugin.TreeDragger', {
extend: 'Ext.AbstractPlugin',
alias: 'plugin.treedrag',
mixins: ['Ext.mixin.Observable'],
constructor: function (config) {
this.mixins.observable.constructor.call(this, config);
},
init: function (component) {
var me = this;
this.source = new Ext.drag.Source({
element: component.element,
handle: '.x-gridrow',
constrain: {
element: true,
vertical: true
},
describe: function (info) {
var row = Ext.Component.from(info.eventTarget, component);
info.row = row;
info.record = row.getRecord();
},
proxy: {
type: 'placeholder',
getElement: function (info) {
console.log('proxy: getElement');
var el = Ext.getBody().createChild({
style: 'padding: 10px; width: 100px; border: 1px solid gray; color: red;',
});
el.show().update(info.record.get('description'));
return el;
}
},
// autoDestroy: false,
listeners: {
scope: me,
beforedragstart: me.makeRelayer('beforedragstart'),
dragstart: me.makeRelayer('dragstart'),
dragmove: me.makeRelayer('dragmove'),
dragend: me.makeRelayer('dragend')
}
});
},
disable: function () {
this.source.disable();
},
enable: function () {
this.source.enable();
},
doDestroy: function () {
Ext.destroy(this.source);
this.callParent();
},
makeRelayer: function (name) {
var me = this;
return function (source, info) {
return me.fireEvent(name, me, info);
};
}
});
树
xtype: 'tree',
hideHeaders: true,
plugins: {
treedrag: {
type: 'treedrag',
listeners: {
beforedragstart: function (plugin, info) {
console.log('listeners: beforedragstart');
}
}
}
},
columns: [{
xtype: 'treecolumn',
flex: 1,
}
]
控制器
afterLoadApportionmentObjectsForTree: function (succes) {
if (succes) {
tree = this.getView().down('tree');
if (tree) {
tree.expandAll();
tree.updateHideHeaders(tree.getHideHeaders());
var store = tree.getStore();
store.remoteFilter = false;
store.filterer = 'bottomup';
this.createDropTargets();
}
}
},
createDropTargets: function () {
var me = this,
rows = tree.innerItems;
Ext.each(rows, function (el) {
var target = new Ext.drag.Target({
element: el.element,
listeners: {
scope: me,
drop: me.onDrop
}
});
});
},
onDrop: function (target, info, eOpts) {
var source = info.record,
row = Ext.Component.from(target.getElement(), tree),
destination = row.getRecord(),
parentNode = source.parentNode;
destination.appendChild(source);
destination.expand();
if (!parentNode.hasChildNodes()) {
parentNode.set('leaf', true);
}
}
编辑
似乎
updateInfo
被称为递归,但我不知道为什么或者如何才能阻止它。我可以自己找到错误。可以将节点拖动到它们自己的子节点上,这与反复添加和删除相同节点有关。为了防止用户这样做,我在我的Ext.drag.Target
中添加了beforeDrop
事件的侦听器。如果目标节点与源节点相同,则返回false
;如果目标节点是源节点的子节点,则返回false
onBeforeDrop: function (target, info, eOpts) {
var source = info.record,
row = Ext.Component.from(target.getElement(), tree),
destination = row.getRecord();
if (source == destination) {
return false;
}
if (source.findChild('number', destination.get('number'), true) != null) {
return false;
}
return true;
}
我还使用beforedragstart
事件来防止移动根节点
也许这对其他人有帮助