如何在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
相关产品推荐
相关产品推荐

