You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Go.js中为预设逻辑门动态添加端口?

Go.js 预设逻辑门动态添加端口解决方案

完全可以给Go.js的预设逻辑门动态添加任意数量的输入/输出端口,核心是利用Go.js的数据驱动特性,将端口定义与节点数据绑定,再通过交互触发数据更新来实现动态渲染。

核心步骤与代码示例

1. 重构逻辑门模板,使用数据绑定定义端口

把原来硬编码的端口改成绑定节点数据中的数组字段(比如inputPorts、outputPorts),让端口数量由数据决定:

// 定义与门模板(其他逻辑门如或门、非门可同理修改)
myDiagram.nodeTemplateMap.add("AndGate",
  $(go.Node, "Vertical",
    { width: 80, height: 100, contextMenu: myContextMenu }, // 绑定右键菜单
    $(go.Shape, "AndGate", { fill: "#eee", stroke: "#000", strokeWidth: 2 }),
    // 左侧输入端口容器
    $(go.Panel, "Vertical",
      { side: go.Side.Left, alignment: go.Spot.Center, spacing: 15 },
      new go.Binding("itemArray", "inputPorts"), // 绑定输入端口数组
      {
        itemTemplate: $(go.Panel, "Auto",
          { portId: "", fromSpot: go.Spot.Left, toSpot: go.Spot.Left }, // 设置端口连接点
          $(go.Shape, "Circle", { width: 12, height: 12, fill: "#fff", stroke: "#333" }),
          new go.Binding("portId", "id") // 绑定唯一端口ID
        )
      }
    ),
    // 右侧输出端口容器
    $(go.Panel, "Vertical",
      { side: go.Side.Right, alignment: go.Spot.Center, spacing: 15 },
      new go.Binding("itemArray", "outputPorts"), // 绑定输出端口数组
      {
        itemTemplate: $(go.Panel, "Auto",
          { portId: "", fromSpot: go.Spot.Right, toSpot: go.Spot.Right },
          $(go.Shape, "Circle", { width: 12, height: 12, fill: "#fff", stroke: "#333" }),
          new go.Binding("portId", "id")
        )
      }
    )
  )
);

2. 实现右键菜单触发端口添加

创建右键菜单,添加“新增输入端口”“新增输出端口”选项,点击时修改节点数据并提交更新:

// 定义右键菜单
const myContextMenu = $(go.Adornment, "Vertical",
  { background: "#f5f5f5", padding: 5 },
  $(go.Button,
    $(go.TextBlock, "新增输入端口"),
    {
      margin: 2,
      click: (e, btn) => {
        const node = btn.part.adornedPart;
        if (!node) return;
        const data = node.data;
        // 生成唯一端口ID
        const newPort = { id: `input-${data.inputPorts.length + 1}` };
        // 提交数据更新,Go.js会自动渲染新端口
        myDiagram.model.commit(model => {
          model.set(data, "inputPorts", [...data.inputPorts, newPort]);
        }, "添加输入端口");
      }
    }
  ),
  $(go.Button,
    $(go.TextBlock, "新增输出端口"),
    {
      margin: 2,
      click: (e, btn) => {
        const node = btn.part.adornedPart;
        if (!node) return;
        const data = node.data;
        const newPort = { id: `output-${data.outputPorts.length + 1}` };
        myDiagram.model.commit(model => {
          model.set(data, "outputPorts", [...data.outputPorts, newPort]);
        }, "添加输出端口");
      }
    }
  )
);

3. 初始化节点数据

在模型中为逻辑门预设初始端口数组:

myDiagram.model = new go.GraphLinksModel(
  [
    {
      key: 1,
      category: "AndGate",
      inputPorts: [{ id: "input-1" }, { id: "input-2" }], // 初始2个输入端口
      outputPorts: [{ id: "output-1" }] // 初始1个输出端口
    }
  ],
  []
);

注意事项

  • 端口唯一性:每个端口的portId必须唯一,避免连接逻辑混乱。
  • 布局适配:通过Panel的spacing属性调整端口间距,保证添加后布局美观。
  • 通用扩展:其他类型的逻辑门(或门、非门等)只需复制模板结构,修改Shape的图形类型即可复用动态端口逻辑。
  • 按钮触发替代:如果不用右键菜单,可在页面添加按钮,通过myDiagram.selection.first()获取选中节点,执行相同的数据更新逻辑。

内容的提问来源于stack exchange,提问作者Wanderer Mister

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 21:35:21