不显示具有 "itemArray" 绑定的面板中的按钮

Buttons in a panel with "itemArray" binding are not displayed

我想在左侧面板中显示一个按钮下拉列表,一个按钮一个"need"。 稍后,用户将能够向列表中添加一个新的需要按钮。 我使用带有 "itemArray" 绑定的面板。 但是当语句:addNeed("My new need");时按钮不显示被执行。 我检查了“dynamicPorts 示例,但我不明白为什么它不起作用。

<!DOCTYPE html>
<html>
<head>
  <meta name="minimumCode" content="width=device-width, initial-scale=1">
  <title>minimumCode</title>
  <meta name="description" content="Iso prototype Leon Levy" />
  <!-- Copyright 1998-2017 by Northwoods Software Corporation. -->
  <meta charset="UTF-8">
  <script src="https://unpkg.com/gojs/release/go-debug.js"></script>
  <span id="diagramEventsMsg" style="color: red"></span>
<script id="code">
var ellipseStrokeWidth=3;
var ellipseWidth = 80;
var ellipseHeight = 25;
var myFont = "16px sans-serif";
var myFontMedium = "23px sans-serif";
var myFontLarge = "30px sans-serif";
var needWidth = 170;
var needHeight = 20;
var needStrokeWidth = 0;
var needColor = 'purple';
var portSize = new go.Size(8, 8);
function init() {
  var $ = go.GraphObject.make;  //for conciseness in defining node templates
  myDiagram =
    $(go.Diagram, "myDiagramDiv",
      {
        "undoManager.isEnabled": true
      });
  myBannerNeeds =
      $(go.Diagram, "myBannerNeedsDiv",
          { layout: $(go.GridLayout, { wrappingColumn: 1, alignment: go.GridLayout.Position
                                      })}
        );
  myBannerNeeds.nodeTemplate =
  $(go.Node,
    $(go.Panel, "Vertical", //needs list buttons
    { alignment: new go.Spot(0, 0), row: 0, column: 0},
      new go.Binding("itemArray", "needsDataArray"),
      { itemTemplate:
          $(go.Panel,
            $(go.Shape, "Rectangle",
              { stroke: "red", strokeWidth: 2,
                height: 30, width: 30}
            ),
          $(go.TextBlock, { text: "...", stroke: "gray" },
          new go.Binding("text", "key"))
          )  // end itemTemplate
      }
    )  // end Vertical Panel
  );
  // Add a button to the needs panel.
  function addNeed(newNeedName) {
    myDiagram.startTransaction("addNeed");
      var button = $('Button',
                 $(go.Shape, "Rectangle",
                     { width: needWidth, height: needHeight, margin: 4, fill: "white",
                      stroke: "rgb(227, 18, 18)", strokeWidth: needStrokeWidth}),
                 $(go.TextBlock, newNeedName,  // the content is just the text label
                   {stroke: needColor, font: myFont }),
                   {click: function(e, obj) { needSelected(newNeedName); } }
                 );
      var needsNode = needsDataArray; //document.getElementById("ForNeeds");
      if (needsNode) { showMessage("needsNode is true; " + button)}
        else {showMessage("needsNode is false")};
        myDiagram.model.insertArrayItem(needsNode, -1, button);
    myDiagram.commitTransaction("addNeed");
  }// end function addNeed
  var needsDataArray = [];
  var linksNeedsDataArray = []; // always empty
  myBannerNeeds.model = new go.GraphLinksModel( needsDataArray, linksNeedsDataArray);
  myDiagram.grid.visible = true;
  myDiagram.model.copiesArrays = true;
  myDiagram.model.copiesArrayObjects = true;
  addNeed("My new need");
  function needSelected(e,obj) {
    alert("e:" + e + "; obj:" + obj + ' selected')
  }; //end function flowTypeSelected
  function showMessage(s) {
    document.getElementById("diagramEventsMsg").textContent = s;
  }
}// end function init
</script>
</head>
<body onload="init()">
  <div id="container" style= "display: grid; grid-template-columns: 1fr 5fr; margin:0 ; height: 800px; width:1080px; font-size:0; position: relative; ">
    <div id="ForNeeds">
      <div id="myBannerNeedsDiv" style="display: inline-block; width: 200px; min-height: 400px; background: whitesmoke; margin-right: 0px;  border: solid 1px purple;">
      </div>
    </div>
    <div id="myDiagramDiv" style="flex-grow: 1; width: 804px;height: 100%; border: solid 1px black;">
    </div>
</div>
</body>
</html>

这是我认为您要求的基本演示:

<!DOCTYPE html>
<html>
<head>
<title>Minimal GoJS Sample</title>
<!-- Copyright 1998-2019 by Northwoods Software Corporation. -->
<meta charset="UTF-8">
<script src="go.js"></script>
<script id="code">
  function init() {
    var $ = go.GraphObject.make;

    myDiagram =
      $(go.Diagram, "myDiagramDiv",
        { "undoManager.isEnabled": true });

    myDiagram.nodeTemplate =
      $(go.Node, "Auto",
        $(go.Shape,
          { fill: "white" }),
        $(go.Panel, "Vertical",
          $(go.TextBlock,
            { margin: 4 },
            new go.Binding("text")),
          $(go.Panel, "Vertical",
            new go.Binding("itemArray", "buttons"),
            {
              itemTemplate:
                $("Button",
                  $(go.TextBlock, new go.Binding("text", "")),
                  {
                    click: function(e, button) {
                      alert(button.data);
                    }
                  }
                )
            }
          )
        )
      );

    myDiagram.model = new go.GraphLinksModel(
    [
      { key: 1, text: "Alpha", buttons: ["one", "two"] },
      { key: 2, text: "Beta", buttons: ["one"] }
    ],
    [
      { from: 1, to: 2 }
    ]);
  }

  function test() {
    myDiagram.commit(function(diag) {
      diag.selection.each(function(n) {
        if (n instanceof go.Node) {
          diag.model.addArrayItem(n.data.buttons, "another");
        }
      })
    })
  }
</script>
</head>
<body onload="init()">
  <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:600px"></div>
  <button onclick="test()">Test</button>
</body>
</html>

Select一个节点然后点击HTML"Test"按钮。它将向节点的 data.buttons 数组添加一个项目,这会导致将 Panel.itemTemplate 的副本添加到该面板。在这种情况下,该项目模板只是一个 GoJS "Button",当单击时调用 alert 以及项目的值,一个字符串。

请注意,添加到数据中 JavaScript 数组的值只是一个简单的对象——在本例中只是一个字符串,尽管每个数组项都是一个 JavaScript 具有各种属性的对象。我认为您的问题是您正在尝试将 GraphObjects 添加到数组中。这是一个禁忌——您不应该将图表的 GraphObjects 与模型数据混合。