【问题标题】:goJS dropdown remove itemsgoJS 下拉列表删除项目
【发布时间】:2018-02-20 18:07:11
【问题描述】:

我有一个简单的 python flask goJS 图形应用程序,如下所示:

节点和链接文本的来源是从应用程序的后端加载的,我将它们设置在model.modelData 部分,如下所示:

var graphDataString = JSON.parse('{{ diagramData | tojson | safe}}');
myDiagram.model = go.Model.fromJson(graphDataString);
myDiagram.model.set(myDiagram.model.modelData, "linkchoices", JSON.parse('{{ link_choices | tojson | safe}}'));
myDiagram.model.set(myDiagram.model.modelData, "nodechoices", JSON.parse('{{ node_choices | tojson | safe}}'));
console.log("whole model");
console.log(myDiagram.model.modelData);

这一切都可以很好地加载到 modelData 中,我可以毫无问题地将其写入控制台:

我的问题是它没有显示在我的节点和链接下拉列表中,我不知道为什么。

这是我的节点模板:

myDiagram.nodeTemplate =
      $(go.Node, "Auto",
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
        // define the node's outer shape, which will surround the TextBlock
        $(go.Shape, "RoundedRectangle",
          {
            parameter1: 20,  // the corner has a large radius
            fill: $(go.Brush, "Linear", { 0: "rgb(254, 201, 0)", 1: "rgb(254, 162, 0)" }),
            stroke: null,
            portId: "",  // this Shape is the Node's port, not the whole Node
            fromLinkable: true, fromLinkableDuplicates: true,
            toLinkable: true, toLinkableDuplicates: true,
            cursor: "pointer"
          }),
        $(go.TextBlock,
          {
            font: "bold 11pt helvetica, bold arial, sans-serif",
            editable: true,  // editing the text automatically updates the model data
            //textEditor: window.TextEditorRadioButtons, // defined in textEditorRadioButtons.js
              // this specific TextBlock has its own choices:
              textEditor: window.TextEditorSelectBox, // defined in extensions/textEditorSelectBox.js
              textEdited: function(tb, oldstr, newstr) {
                var currentNodeChoices = tb.diagram.model.modelData.nodechoices;
                console.log("currentNodeChoices");
                console.log(currentNodeChoices);
                console.log("newstr");
                console.log(newstr);
                console.log("oldstr");
                console.log(oldstr);
                var idx = currentNodeChoices.indexOf(newstr);
                if (idx >= 0 && oldstr !== newstr) {
                  console.log("removing choice " + idx + ": " + newstr);
                  var newNodeChoices = Array.prototype.slice.call(currentNodeChoices);
                  newNodeChoices.splice(idx, 1);
                  tb.diagram.model.set(tb.diagram.model.modelData, "nodechoices", newNodeChoices);
                }
              }
          },
        new go.Binding("text").makeTwoWay(),
        new go.Binding("nodechoices").ofModel())
    ); 

这是我的链接模板:

myDiagram.linkTemplate =
      $(go.Link,  // the whole link panel
        {
          curve: go.Link.Bezier, 
          adjusting: go.Link.Stretch,
          reshapable: true, 
          relinkableFrom: true, 
          relinkableTo: true,
          toShortLength: 3
        },
        new go.Binding("points").makeTwoWay(),
        new go.Binding("curviness"),
        $(go.Shape,  // the link shape
          { strokeWidth: 1.5 }),
        $(go.Shape,  // the arrowhead
          { toArrow: "standard", stroke: null }),
        $(go.Panel, "Auto",
          $(go.Shape,  // the label background, which becomes transparent around the edges
          {
              fill: $(go.Brush, "Radial", { 0: "rgb(240, 240, 240)", 0.3: "rgb(240, 240, 240)", 1: "rgba(240, 240, 240, 0)" }),
                stroke: null
            }),
            $(go.TextBlock,
            {
              background: "white",
              editable: true,
              textEditor: window.TextEditorSelectBox, // defined in extensions/textEditorSelectBox.js
              textEdited: function(tb, oldstr, newstr) {
                var currentLinkChoices = tb.diagram.model.modelData.linkchoices;
                console.log("currentLinkChoices");
                console.log(currentLinkChoices);
                console.log("newstr");
                console.log(newstr);
                console.log("oldstr");
                console.log(oldstr);
                var idx = currentLinkChoices.indexOf(newstr);
                if (idx >= 0 && oldstr !== newstr) {
                  console.log("removing choice " + idx + ": " + newstr);
                  var newLinkChoices = Array.prototype.slice.call(currentLinkChoices);
                  newLinkChoices.splice(idx, 1);
                  tb.diagram.model.set(tb.diagram.model.modelData, "linkchoices", newLinkChoices);
                }
              }
            },
            new go.Binding("text").makeTwoWay(),
            new go.Binding("linkchoices").ofModel())
        )
    );

我想完成此行为:用户可以添加新节点和链接,但用户只能从链接和节点的下拉列表中选择可用选项。添加新节点和链接工作正常,我没有任何问题。我想这样做,当用户对节点使用一个选项时,该选项将不再可用,直到他删除该节点或将其更改为其他选项。

例如,他使用“node_choice_1”他不能再在任何其他节点上使用它,直到他更改该节点上的该选项或删除节点。链接也是如此。 所以我将此代码添加到我的图表定义中:

myDiagram =
    $(go.Diagram, "myDiagramDiv",  // must name or refer to the DIV HTML element
    {
      // start everything in the middle of the viewport
      initialContentAlignment: go.Spot.Center,
      // have mouse wheel events zoom in and out instead of scroll up and down
      "toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom,
      // support double-click in background creating a new node
      "clickCreatingTool.archetypeNodeData": { text: "new node" },
      // enable undo & redo
      "textEditingTool.defaultTextEditor": window.TextEditorSelectBox,
      "undoManager.isEnabled": true,
      "layout": new go.ForceDirectedLayout(),
      "ModelChanged": function(e) {
        console.log("Diagram model changed!");
              if (e.change === go.ChangedEvent.Remove && e.modelChange === "linkDataArray") {
                console.log("eee");
                console.log(e);
                var linkdata = e.oldValue;
                console.log("linkdata");
                console.log(linkdata);
                var oldstr = linkdata.text;
                console.log("oldstr");
                console.log(oldstr);

                if (!oldstr) return;
                var currentLinkChoices = e.model.modelData.linkchoices;
                console.log("currentLinkChoices");
                console.log(currentLinkChoices);
                var idx = currentLinkChoices.indexOf(oldstr);
                if (idx < 0) {
                  console.log("adding choice: " + oldstr);
                  var newLinkChoices = Array.prototype.slice.call(currentLinkChoices);
                  newLinkChoices.push(oldstr);
                  e.model.set(e.model.modelData, "linkchoices", newLinkChoices);
                }
              }
              else if(e.change === go.ChangedEvent.Remove && e.modelChange === "nodeDataArray"){
                console.log("eee");
                console.log(e);
                var nodedata = e.oldValue;
                console.log("nodedata");
                console.log(nodedata);
                var oldstr = nodedata.text;
                console.log("oldstr");
                console.log(oldstr);

                if (!oldstr) return;
                var currentNodeChoices = e.model.modelData.nodechoices;
                console.log("currentNodeChoices");
                console.log(currentNodeChoices);
                var idx = currentNodeChoices.indexOf(oldstr);
                if (idx < 0) {
                  console.log("adding choice: " + oldstr);
                  var newNodeChoices = Array.prototype.slice.call(currentNodeChoices);
                  newNodeChoices.push(oldstr);
                  e.model.set(e.model.modelData, "nodechoices", newNodeChoices);
                }

              }
            }
    });

此外,当节点没有更多可用的节点选项时,用户无法添加更多节点。链接也是如此。

我真的很绝望,因为我试图让这个简单的事情发挥作用,但我被困在原地好几天了。我试图阅读文档,但没有发现任何有用的东西,有很多记录在案的案例,但没有我需要的示例。任何帮助将不胜感激。

【问题讨论】:

    标签: javascript python flask gojs


    【解决方案1】:

    我之前似乎已经为链接回答过这个问题,所以我采用了相同的代码并将其全部复制到节点上。我确实改进了textEdited 事件处理程序来处理撤消/重做,尽管对于console.log 的所有调用显然更加冗长。

    function init() {
      var $ = go.GraphObject.make;
    
      myDiagram =
        $(go.Diagram, "myDiagramDiv",
          {
            initialContentAlignment: go.Spot.Center,
            "undoManager.isEnabled": true,
            "ModelChanged": function(e) {     // just for demonstration purposes,
              if (e.isTransactionFinished) {  // show the model data in the page's TextArea
                document.getElementById("mySavedModel").textContent = e.model.toJson();
              }
              if (e.change === go.ChangedEvent.Remove) {
                if (e.modelChange === "linkDataArray") {
                  var linkdata = e.oldValue;
                  var oldstr = linkdata.text;
                  if (!oldstr) return;
                  var linkchoices = e.model.modelData.linkchoices;
                  var idx = linkchoices.indexOf(oldstr);
                  if (idx < 0) {
                    console.log("deletion adding link choice: " + oldstr);
                    var newlinkchoices = Array.prototype.slice.call(linkchoices);
                    newlinkchoices.push(oldstr);
                    e.model.set(e.model.modelData, "linkchoices", newlinkchoices);
                  }
                } else if (e.modelChange === "nodeDataArray") {
                  var nodedata = e.oldValue;
                  var oldstr = nodedata.text;
                  if (!oldstr) return;
                  var nodechoices = e.model.modelData.nodechoices;
                  var idx = nodechoices.indexOf(oldstr);
                  if (idx < 0) {
                    console.log("deletion adding node choice: " + oldstr);
                    var newnodechoices = Array.prototype.slice.call(nodechoices);
                    newnodechoices.push(oldstr);
                    e.model.set(e.model.modelData, "nodechoices", newnodechoices);
                  }
                }
              }
            }
          });
    
      myDiagram.nodeTemplate =
        $(go.Node, "Auto",
          $(go.Shape,
            { fill: "white", portId: "", fromLinkable: true, toLinkable: true, cursor: "pointer" },
            new go.Binding("fill", "color")),
          $(go.TextBlock,
            {
              margin: 8,
              editable: true,
              textEditor: window.TextEditorSelectBox, // defined in extensions/textEditorSelectBox.js
              textEdited: function(tb, oldstr, newstr) {
                if (oldstr !== newstr) {
                  console.log("changing from " + oldstr + " to " + newstr);
                  var model = tb.diagram.model;
                  var nodechoices = model.modelData.nodechoices;
                  if (!nodechoices) {
                    nodechoices = [];
                    model.set(model.modelData, "nodechoices", nodechoices);
                  }
                  var idx = nodechoices.indexOf(newstr);
                  if (idx >= 0) {
                    console.log("removing node choice " + idx + ": " + newstr);
                    model.removeArrayItem(nodechoices, idx);
                  }
                  if (oldstr) {
                    console.log("  adding node choice " + oldstr);
                    model.addArrayItem(nodechoices, oldstr);
                  }
                }
              }
            },
            new go.Binding("text").makeTwoWay(),
            new go.Binding("choices", "nodechoices").ofModel())
        );
    
      myDiagram.linkTemplate =
        $(go.Link,
          $(go.Shape),
          $(go.Shape, { toArrow: "OpenTriangle" }),
          $(go.TextBlock,
            {
              background: "white",
              editable: true,
              textEditor: window.TextEditorSelectBox, // defined in extensions/textEditorSelectBox.js
              textEdited: function(tb, oldstr, newstr) {
                if (oldstr !== newstr) {
                  console.log("changing from " + oldstr + " to " + newstr);
                  var model = tb.diagram.model;
                  var linkchoices = model.modelData.linkchoices;
                  if (!linkchoices) {
                    linkchoices = [];
                    model.set(model.modelData, "linkchoices", linkchoices);
                  }
                  var idx = linkchoices.indexOf(newstr);
                  if (idx >= 0) {
                    console.log("removing link choice " + idx + ": " + newstr);
                    model.removeArrayItem(linkchoices, idx);
                  }
                  if (oldstr) {
                    console.log("  adding link choice " + oldstr);
                    model.addArrayItem(linkchoices, oldstr);
                  }
                }
              }
            },
            new go.Binding("text").makeTwoWay(),
            new go.Binding("choices", "linkchoices").ofModel())
        );
    
      myDiagram.model = new go.GraphLinksModel(
      [
        { key: 1, text: "Alpha", color: "lightblue" },
        { key: 2, text: "Beta", color: "orange" },
        { key: 3, text: "Gamma", color: "lightgreen" },
        { key: 4, text: "Delta", color: "pink" }
      ],
      [
        { from: 1, to: 2, text: "one" },
        { from: 1, to: 3, text: "two" },
        { from: 3, to: 4, text: "three" }
      ]);
      myDiagram.model.set(myDiagram.model.modelData, "nodechoices", ["Epsilon"]);
      myDiagram.model.set(myDiagram.model.modelData, "linkchoices", ["four"]);
    }
    

    【讨论】:

    • 非常感谢!这部分new go.Binding("choices", "linkchoices").ofModel())困扰着我。我希望在modelData 的文档中通过示例更好地解释这一点。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2021-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多