拖动排序问题
拖动排序
Ext.data.NodeInterface 这个对象还树形treepanel是很重要的。store里面存放的都是这个。展开、Expaned或者折叠。
相关知识
- 快速查找相关的工具,比如grid插件,通过这个关键字 grid.plugin
- DragDrop源码,这个插件源码非常简单,里面有个重要的函数,onViewRender。其中有一行代码:
ownerGrid.relayEvents(view, ['beforedrop', 'drop']);
所以从Ext.mixin.Observable中查找到这个relayEvents函数,主要功能是用来传递事件。即将插件的触发的事件传递到grid表格。
问题分析
从后端来说,为了满足排序,必须额外使用一个字段辅助排序。但是增加这个字段order,给一个默认值,比如100,又不会增加额外的编程难度。(排序,并不是更换两个id)。总结:目前还是没有好的想法,最简单粗暴的处理方式就是,前端直接将一个分组内的排序,告诉后端,后端直接进行遍历,从0开始增加1。(字段默认也是从0开始)。但是这样的问题是,业务处理代码简单,但是数据库增加了不必要的操作。(暂定此方法。)
从前端来说,需要支持拖拽排序。从网上找到了Ext的这个插件的用法。但是细节还不清楚。参见文章,代码基本可用。
核心代码:
viewConfig: {
plugins: {
ptype: "gridviewdragdrop",
dragText: "可用鼠标拖拽进行上下排序"
}
},
实现Grid行的上下移动
Ext.onReady(function() {
var proStore = Ext.create("Ext.data.Store", {
fields: ["code", "name", "num"],
data: [
["#001", "iPhone6", 100],
["#002", "iPhone6 Plus", 80],
["#003", "Mi Note4", 99],
["#004", "Galaxy S6", 75],
["#005", "Smartisan T2", 68]
]
});
Ext.create("Ext.grid.Panel", {
title: "可用鼠标拖拽行数据的Grid",
width: 400,
margin: 10,
border: true,
store: proStore,
columns: [{
text: "产品编号",
dataIndex: "code",
flex: 1
}, {
text: "产品名称",
dataIndex: "name",
flex: 1
}, {
text: "产品数量",
dataIndex: "num",
flex: 1
}],
viewConfig: {
plugins: {
ptype: "gridviewdragdrop",
dragText: "可用鼠标拖拽进行上下排序"
}
},
renderTo: Ext.getBody()
});
});
实现多个Grid之间的相互移动
要让行数据可在多个Grid之间相互移动,只需在Grid引用Ext.grid.plugin.DragDrop插件时,为其指定同一个组名,表明它们属于同一组,可相互移动。
当然,前提是这些Grid使用的Model类应该一致,即表格字段应该一致。
viewConfig: {
plugins: {
ptype: "gridviewdragdrop",
ddGroup: "DrapDropGroup"
}
}
开始处理代码
版本说明:使用的是Ext5.1.0.107版本。使用6.5中的手册写法略有不同。
问题
- 插件的事件无法监听到。解决办法,写到viewConfig的listeners中。
//备注:me指代的是grid。另外写在grid的listeners也没有反应。
me.on('beforedrop',function(node, data, overModel, dropPosition, dropHandlers) {
- 找到排序后的数据
只是简单的跟了一个位置before、after。通过store.getData获取到数据。
- 理解事件传递的值,解决了判断,该节点能不能拖拽到节点
当前拖动的记录:data.records[0]
目标的记录:overModel
相对位置关系:dropPosition
父节点,默认只展开一级。代码写了,却没有效果。
显示优化问题
如果重新加载数据,则数据全部重新刷新了。原来展开的,折叠住了。如果不刷新吧,那么拖动末个节点,显示异常。
- 展开节点问题
必须使用Ext.data.NodeInterface提供的expand、collapse等方法。而不能通过record.set方法来实现。注意跟checked的区别。
/************
2019/4/2
只展开顶级节点
************/
expandTopRecord:function(){
var me=this;
var root = me.store.getRoot();
Ext.Array.each(root.childNodes,function(node){
//注意不能使用//node.set('expanded',false);
node.collapse();
});
},
//官方手册
Ext.grid.plugin.DragDrop
drop ( node, data, overModel, dropPosition, eOpts )
// 官方例子 build/examples/kitchensink/?classic#dd-grid-to-grid
onDropGrid1: function (node, data, dropRec, dropPosition) {
this.onDrop(dropRec, data.records[0], dropPosition, 'Drag from right to left');
},
- 范围
简单的处理逻辑
//me.getdog();
var view=me.getView();
view.on('beforedrop',function(node, data, overModel, dropPosition, dropHandlers) {
// Defer the handling
//dropHandlers.wait = true;
//1、判断当前节点,
//一级节点,则进行折叠
//否则,停止拖动前进行判断,如果合适,则允许放入。
/*Ext.MessageBox.confirm('Drop', 'Are you sure', function(btn){
if (btn === 'yes') {
dropHandlers.processDrop();
} else {
dropHandlers.cancelDrop();
}
});*/
});
view.on('drop',function(node, data, overModel, dropPosition, eOpts) {
//获取排序后的数据console.log(me.store.getData());
//根据当前节点ParentID,过滤出该组的数据。
//然该组数据发送致后台
});
正式代码
var view=me.getView();
//注意,使用这种方式进行监听
view.on('beforedrop',function(node, data, overModel, dropPosition, dropHandlers,eOpts) {
// Defer the handling
dropHandlers.wait = true;
var curRd=data.records[0];
//判断当前节点,是否可移动,同一组内可移动。
if(curRd.get('ParentID')!=overModel.get('ParentID')){
dropHandlers.cancelDrop();
}else{
dropHandlers.processDrop();
}
});
view.on('drop',function(node, data, overModel, dropPosition, eOpts) {
//获取排序后的数据console.log(me.store.getData());
var curRd=data.records[0];
var pid=curRd.get('ParentID');
var Rds=me.store.getData().items;
//根据当前节点ParentID,过滤出该组的数据。
var fRds=Ext.Array.filter(Rds,x=>x.get('ParentID')==pid);
var ids=Ext.Array.map(fRds,x=>x.get('GroupID'));
//然该组数据发送致后台
Ext.Ajax.request({
url: '/admin/device/Terminal/orderterminalgroup/',
params: {'ids': Ext.encode(ids)},
method: 'POST',
success: function(response, option)
{
//记录当前折叠状态
me.updateExpandIds();
//更新树木,避免显示乱问题
me.store.reload();
//但是如果更新了,节点展开的就关闭了
},
failure: function(){}
});
});
//node.set('expanded',false); 除了数据加载阶段可用
//其他阶段不可用,应使用expand函数等
/************
2019/4/2
记录展开的id。此方法不是递归的,所以呢,只能处理简一层。
************/
updateExpandIds:function(){
var me=this;
var root = me.store.getRoot();
me.expandIds=[];
Ext.Array.each(root.childNodes,function(node){
if(node.data.expanded===true){
me.expandIds.push(node.data.GroupID);
}
});
},
//在store.load时,更新expand状态
Ext.Array.each(records,function(rd){
if(Ext.Array.indexOf(me.expandIds,rd.get('GroupID'))!==-1){
rd.set({expanded:true});//此时可用,因为树还没有重新渲染
}
});