我想知道是否有办法在 dojo Dnd 中以编程方式移动节点?原因是当 Web 服务调用触发数据库保存失败时,我想恢复对拖放的更改。这是我到目前为止所拥有的。

在我的代码中,节点 ID 似乎无法被 dojo.dnd.Container.DelItem 识别。我不能只使用目标上的所选项目,因为这是一个异步 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;
}
有帮助吗?

解决方案

看起来你假设 delItem 删除物理节点。看看 文档 - 可能您想在容器之间移动节点而不是从地图中删除它们。一种简单的方法就是在容器之间移动 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();
}

或者类似的东西应该有效。重要的部分:

  • 使用您认为合适的任何 DOM 操作将节点从一个父节点移动到另一个父节点。我用了 appendChild(), ,但你可以使用 insertBefore(), ,或其他任何东西。
  • 移动后同步涉及的两个源。

显然,如果两个源都使用相同类型和结构的节点,则它可以工作。如果没有,您应该做一些更复杂的事情,例如,通过发布文档中描述的主题来移动您需要的所有内容,模拟真正的 DnD 移动。

其他提示

我有这个功能,通过按钮点击移动选定的节点:

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)

我现在也在做同样的事情。我能够通过执行以下操作来解决。

  • 将 dnd/Source autoSync 属性设置为 true

<div data-dojo-type="dojo.dnd.Source" accept="widget" class="source" data-dojo-props="autoSync: true">

拖动后它会丢失 dndtype,因此我必须使用客户端代码重新添加它。另外,我在放置后删除了 dojoDndItemAnchor 类。

$(node).removeClass('dojoDndItemAnchor').attr('dndtype', 'widget');

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top