我想知道是否有办法在dojo Dnd中以编程方式移动节点?原因是我希望在Web服务调用触发数据库上的失败保存时将更改还原为拖放。这是我到目前为止所拥有的。
在我的代码中,dojo.dnd.Container.DelItem似乎无法识别节点Id。我不能只使用目标上的选定项目,因为这是一个异步的Web服务函数回调。因此,当调用此方法时,用户可能正在选择容器上的另一个节点。
function OnMoveWSComplete(strResult) {
var resultObj = eval('(' + strResult + ')');
var sourceContainer = eval('(' + objResult.sourceContainerId + ')');
var targetContainer = eval('(' + objResult.targetContainerId + ')');
var targetNodes = targetContainer.getAllNodes();
for (var iNode = 0; iNode < targetNodes.length; iNode++) {
var currId = getLastIdFromStr(targetNodes[iNode].id);
if (currId == resultObj.Id) {
var targetN = targetNodes[iNode];
var Name = targetNodes[iNode].childNodes[0].nodeValue;
targetContainer.delItem(targetNodes[iNode].id);
var origData = { Id: resultObj.Id, Name: Name };
sourceContainer.insertNodes(true, origData);
break;
}
}
}
编辑:解决方案(感谢Eugene Lazutkin)[2009/11/30]:
/**
* Move one node from one container to the other
*/
function moveNode(nodeId, sourceContainer, targetContainer) {
var node = dojo.byId(nodeId);
// Save the data
var saveData = sourceContainer.map[nodeId].data;
// Do the move
sourceContainer.parent.removeChild(node);
targetContainer.parent.appendChild(node);
// Sync the DOM object → map
sourceContainer.sync();
targetContainer.sync();
// Restore data for recreation of data
targetContainer.map[nodeId].data = saveData;
}
答案 0 :(得分:3)
看起来您假设delItem
删除了物理节点。看看documentation - 可能你想在容器之间移动节点而不是从地图中删除它们。一种简单的方法就是在容器之间移动DOM节点,并在两个容器上调用sync()
。
添加:这是一个超级简单的伪代码示例:
function move(node, source, target){
// normalize node and/or node id
node = dojo.byId(node);
// move it physically from one parent to another
// (from target to source) adding to the end
target.parent.appenChild(node);
// now it is moved from source to target
// let's synchronize both dojo.dnd.Source's
source.sync();
target.sync();
}
或者沿着这些方向的东西应该有用。重要的部分:
appendChild()
,但您可以使用insertBefore()
或其他任何内容。显然,如果两个源都使用相同类型和结构的节点,则它可以工作。如果没有,您应该做一些更复杂的事情,例如,通过发布文档中描述的主题,移动您需要模仿真正DnD移动的所有内容。
答案 1 :(得分:2)
我有这个功能,通过按钮点击移动选定的节点:
source.forInItems(dojo.hitch(this, function(item, id, map) {
if (dojo.hasClass(id, "dojoDndItemAnchor")) {
target.onDrop(source, [ dojo.byId(id) ], false);
dojo.removeClass(id, "dojoDndItemAnchor");
}
}));
onDrop()
是一个可覆盖的方法,在项目删除时调用,默认情况下调用方法onDropExternal(source, nodes, copy)
。
答案 2 :(得分:0)
我现在正在做同样的事情。我能够通过以下方式解决问题。
<div data-dojo-type="dojo.dnd.Source" accept="widget" class="source" data-dojo-props="autoSync: true">
拖动后它会丢失dndtype,所以我不得不使用客户端代码重新添加它。我也会在删除后删除dojoDndItemAnchor类。
$(node).removeClass('dojoDndItemAnchor').attr('dndtype', 'widget');