Dorado 9 : 2. 控件拖拽(DCUG)

拖拽的基本使用

本文主要介绍集合控件之间的拖拽。所谓集合控件是指DataListBox, Grid, Tree, BlockView这种集合类型的控件。

以下图我们简要说明拖拽的基本使用--我们希望左边的Block中的元素可以拖拽到右上侧的Block中:

首先要针对不同操作的控件设置dragable和droppable属性

则首先要设置如下的属性:

左边的Block要设置dragable为true,表示左边的控件支持drag(出坞)

右边的block的droppable为true,表示右边的控件支持drop(入坞)

其次要设置dragTags和droppableTags

当页面上有多个控件之间允许拖拽的时候,如下图:

我们希望左侧上方的Block控件不允许拖拽到右下方。对于右下方的ListBox控件来说,如果仅仅根据被拖拽对象的dragable和自身的dropable属性是无法区分被拖拽过来的是左上方的BlockView还是左下方的BlockView,为更好的实现这种需求,我们对入坞和出坞设计了tags属性:dragTags和droppableTags:

拖拽时系统自动判断被拖拽对象的dragTags与入坞的目标对象的droppableTags属性是否匹配,如果匹配就允许入坞。

这就如同海港与海船之间的关系:

海港声明了本海港只允许军舰入港,当一首船过来后声明我是军舰,则允许入坞,当一艘渔船过来则不允许入坞。

另为提高港口的使用效率,我们可以使港口可以同时容纳不同类型的船,同时也允许船具有多中功能。如:港口允许停放军舰和海监船。

与此相应的技术实现是:

droppable就可以设置为多个标记"WarShip,OceanSurveillanceShip",用逗号隔开。

同理dragTags也允许多个标记的写法。

最终只要有一个匹配上就允许入坞,基本算法:

if (({入坞船.dragTags} ∩ {港口.droppableTags}) != φ){
    //允许入坞
}else{
    //拒绝入坞
}

 

拖拽相关的方法说明

onDragStart

当被拖拽对象被拖离自身位置时触发该事件,一般情况下我们并不需要特别为此事件定义代码,Dorado控件会自动初始化拖拽的draggingInfo信息,默认情况下draggingInfo中的object和sourceControl属性就是控件自身。

对于Collection集合类型的对象,object就是子元素,如:Tree拖拽时object就是Node, Grid拖拽时object属性就是行对应的数据实体对象,BlockView对象object属性就是Block。

当然你可以在该事件定制draggingInfo中的object属性:

// @Bind #button1.onDragStart
!function(self, arg) {
	arg.draggingInfo.set("object", object);
}

onDragStop

该事件慎用,onDragStop表示拖拽停止,但是要注意取消拖拽也会触发该事件,因此正常情况下拖拽结束后你的业务逻辑代码应该写在onDraggingSourceDrop中

onDraggingSourceDrop

这是释放被拖拽的控件对象时触发的事件,通常在该事件中完成释放后的业务逻辑代码的编写。该事件与onDragStart事件对于,我们可以从arg.draggingInfo中获取被拖拽的控件对象的基本信息:

1.获取被拖拽的控件对象

var control = arg.draggingInfo.get("sourceControl");

2.对于BlockView,Tree,Grid集合类型的控件,你还可以获取内部被拖拽的子元素:

var object = arg.draggingInfo.get("object");

一个参考范例(拖拽后修改被拖拽节点数据实体的parentId的实例)

var sourceObject = arg.draggingInfo.get("object");
var targetObject = arg.draggingInfo.get("targetObject");
var sourceEntity = sourceObject.get("data");
var targetEntity = targetObject.get("data");
sourceEntity.set("parentMenuResourceId", targetEntity.get("id"));

拖拽对数据持久化的影响

STATE_MODIFY和STATE_MOVED重合之处

 

控件拖拽

/** @View */
function dragPanel(draggingInfo, extraInfos) {
	var object = draggingInfo.get("object");
	var source = object;
	while (source){
		source = source.get("parent");
		if (source instanceof dorado.widget.Container){
			break;
		}
	}
	source.removeChild(object);
	source.get("children").each(function(control){
		if ("center"==control.get("layoutConstraint.type")){
			source.removeChild(control);
			source.addChild(control);
		}
	});
	source.resetDimension(300);
	var target = draggingInfo.get("targetControl");
	while (target){
		if (target instanceof dorado.widget.Container){
			break;
		}
		target = target.get("parent");
	}
	if (extraInfos){
		object.set(extraInfos);
	}
	target.addChild(object);
	object.resetDimension(300);
}

// @Bind #container1.onDraggingSourceDrop
!function(self, arg) {
	dragPanel(arg.draggingInfo, {
		layoutConstraint: {type: "top"},
		height: 50
	});
}

// @Bind #container2.onDraggingSourceDrop
!function(self, arg) {
	dragPanel(arg.draggingInfo, {
		layoutConstraint: {type: "center"},
		height: "100%"
	});
}

控件内部对象拖拽

Attachments:

Draggable.PNG (image/png)
DragTags.PNG (image/png)
Draggable2.png (image/png)
DragTags2.png (image/png)