ExtJS重新排序树时,超出了最大调用堆栈大小 [英] ExtJS Maximum call stack size exceeded when reordering tree

查看:79
本文介绍了ExtJS重新排序树时,超出了最大调用堆栈大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过拖放对树的层次结构进行重新排序。移动多个节点后,出现错误 Uncaught RangeError:超出最大调用堆栈大小。错误显示在 NodeInterface.js 中。 updateInfo 函数在以下行中崩溃

I'm reordering the hierarchy of a tree with drag and drop. After moving multiple nodes I get the error Uncaught RangeError: Maximum call stack size exceeded. The error appears in NodeInterface.js. The updateInfo function crashes in the following line

for(i = 0; i< ; childCount; i ++){
children [i] .updateInfo(commit,childInfo);
}

什么可能导致此问题?

以下代码显示了我如何在ExtJS 6.5.2中实现拖放和重新排序。也许您可以找到导致问题的原因。

The following code shows how I implemnted the drag and drop and reordering in ExtJS 6.5.2. Maybe you can find what's causing the problem.

插件

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 被称为递归,但我不知道为什么或如何防止它。

It seems that updateInfo is called recursive, but I can't figure out why or how I could prevent it.

推荐答案

我可以自己发现错误。可以将节点拖到自己的子节点上,这与一次又一次地递归添加和删除相同的节点有关。为了防止用户执行此操作,我在 Ext.drag.Target 中为 beforeDrop 事件添加了一个侦听器。如果目标节点与源节点相同,则返回 false ,如果目标节点与源节点相同,则返回 false 是源节点的子节点。

I could find the mistake by myself. It was possible to drag nodes on their own children which relates to an recursive adding and removing of the same nodes over and over again. To prevent the user from doing this, I added an listener for the beforeDrop event to my Ext.drag.Target. There it returns false, if the target node is the same as the source node and it returns false if the target node is a child node of the source node.

 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 防止移动根节点的事件。

I also used the beforedragstart event to prevent moving the root node.

也许这对其他人很有帮助。

Maybe this is helpful for someone else.

这篇关于ExtJS重新排序树时,超出了最大调用堆栈大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆