ExtJS在现代工具箱中拖放到树中

时间:2018-08-06 13:15:06

标签: extjs drag-and-drop extjs6-modern

实际上,我将实现一个树形视图,在该视图中,用户应该可以选择通过拖放对结构进行重新排序。实际上我不知道如何启用拖放功能。我使用“ treeviewdragdrop”插件找到了很多示例,该插件仅与经典工具包一起使用。

以下代码使我移动了第一个节点,但没有更多。

this.toParentSource = new Ext.drag.Source({
                element: this.getView().element.down('.x-gridcell'),
                constrain: {
                    element: this.getView().body,
                    vertical: true
                }
            });

您能帮我解决这个问题吗?我正在使用ExtJS 6.5.2现代工具包。

1 个答案:

答案 0 :(得分:1)

这是我在现代Ext JS中启用树的拖放的方式:

首先,我编写了一个插件,该插件创建应可拖动的源。

插件

  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) {
                    // logic to identify the root and prevent it from being moved
                    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,
                beforeDrop: me.onBeforeDrop
            }
        });
    });
},

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

onBeforeDrop: function (target, info, eOpts) {
    var source = info.record,
        row = Ext.Component.from(target.getElement(), tree),
        destination = row.getRecord();
    // prevent the user to drop the node on itself
    // this would lead to an error caused by recursive method calls 
    if (source == destination) {
        return false;
    }
    // prevent the user to drop a node on it's children
    // this would lead to an error caused by recursive method calls
    if (source.findChild('number', destination.get('number'), true) != null) {
        return false;
    }

    return true;
}