GoJS 在不知道 parent 个节点的密钥的情况下删除 child 个节点

GoJS delete child nodes without knowing parent node's key

我有一个带有自定义模型的 goJS 图。当在另一个节点上放置一个节点时,我 link 它们在 mouseDrop 触发时设置 link 数据中的 from 和 to diagram.model:

mydiagram.model.addLinkData({ from: oldNodeModel.key, to: dragNodeModel.key });

一切正常。在我的节点模板中,我有一个自定义模板,它在带有删除按钮的节点周围放置了一个面板。这个删除按钮只是一个带有点击事件的图片。

现在,当我单击删除 image/button 时,我想立即删除它及其所有 child 个节点。

我的问题是找不到 children。

我有像 findNodesOutOf 这样的用户事件,它不会产生任何结果,而 findNodesConnected 会找到 parents 和 child 节点并删除该批次 - 这不是我想要的想要。

知道如何解决这个问题吗?

您可以使用 diagram.selection:

获取要删除的项目
var nodeToDelete = mydiagram.selection.iterator.first();

接下来要查找此节点的所有子节点,我推荐一个递归函数,它将执行以下操作:

  1. 取入要删除的节点,
  2. 使用mydiagram.getChildrenNodes(nodeToDelete)
  3. 找到所有连接到它的节点
  4. 通过连接的节点进行迭代
  5. 检查每个节点是否是子节点,使用 linkNodeModel 并检查 link 从当前节点到子节点。
  6. 然后用这个子节点再次调用递归函数
  7. 递归函数将return一个包含所有子节点的数组

然后你就可以删除它们了。

您的代码将如下所示:

function deleteNode()
{
    // TAKE NOTE - This will get all selections so you need to handel  this
    // If you have multiple select enabled
    var nodeToDelete = mydiagram.selection.iterator.first();    
    var childNodes = getChildNodes(deletedItem);

    //Remove linked children
    $.each(childNodes, function()
    {
         myDiagram.remove(this);
    });

    // Then also delete the actual node after the children was deleted
    // TAKE NOTE - This will delete all selections so you need to handle this
    // If you have multiple select enabled
    mydiagram.commandHandler.deleteSelection();
}

递归函数不断检查每个节点的子节点并将它们添加到数组中:

function getChildNodes(deleteNode)
{
    var children = [];
    var allConnected= deleteNode.findNodesConnected();

    while (allConnected.next())
    {
        var child = allConnected.value;

        // Check to see if this node is a child:
        if (isChildNode(deleteNode, child))
        {
            // add the current child
            children.push(child);

            // Now call the recursive function again with the current child
            // to get its sub children
            var subChildren = getChildrenNodes(child);

            // add all the children to the children array
            $.each(subChildren, function()
            {
                children.push(this);
            });
       }
   }

    // return the children array
    return children;
}

此函数将通过查看图中的 links 并对照当前节点和子节点来回检查来检查节点是否为子节点:

function isChildNode(currNode, currChild)
{
    var links = myDiagram.links.iterator;
    while (links.next())
    {
        // Here simply look at the link to determine the direction by checking the direction against the currNode and the child node. If from is the current node and to the child node
        // then you know its a vhild
        var currentLinkModel = links.value.data;
        if (currentLinkModel.from === currNode.data.key &&   currentLinkModel.to === currChild.data.key)
        {
             return true;
        }
    }
    return false;
}