Transactions about modifying node data


#1
function updateProprerty() {
   myDiagram.selection.each(function(node) {
       for (var para in node.data) { 
         var nodeData = node.data;
         var oldValue = node.data[para];
         var newValue = $("#p_" + para).val();
         if (para != "isgroupnode"&&oldValue !=newValue) {
            myDiagram.startTransaction("update nodeProperty");
            myDiagram.model.setDataProperty(nodeData, para, newValue);
            myDiagram.commitTransaction("update nodeProperty");
          }
       }
   });
}

As shown in the code, I want to modify the datum for the selected node.
If you use this method on the same Node several times, only the first time you successfully modify the properties of the node in the myDiagram.
How can I improve the method so that changes in nodes can be timely reflected in the myDiagram?


#2

You do not want to execute a transaction within a loop. That is a general policy that is true for all programming, not just for GoJS. Really you want only a single top-level transaction per user gesture.


#3

For a node, I might change more than one parameter at a time. And modify the same node multiple times.
I changed the code so that the method only needs to perform a transaction commit once.
But the updateProprerty() method can only be successful once for each node in the myDiagram. Why?

function updateProprerty() {
 myDiagram.selection.each(function(node) {
   myDiagram.startTransaction("update nodeProperty");
   for (var para in node.data) { 
     var nodeData = node.data;
     var oldValue = node.data[para];
     var newValue = $("#p_" + para).val();
     if (para != "isgroupnode"&&oldValue !=newValue) {
        myDiagram.model.setDataProperty(nodeData, para, newValue);
      }
   }
   myDiagram.commitTransaction("update nodeProperty");
 });
}

#4

My guess is that you are setting to undefined some properties that you should not be touching on the node.data object. It would be better not to iterate over all of the properties on the data.


#5

Is there a better way than setDataProperty to modify node.data without iterating over them?
After debugging, I found that myDiagram.model.nodedataArray has been modified, but the myDiagram has not been refreshed.
Once the binding data is modified, isn’t the myDiagram automatically refreshed?
Is there a way to refresh the myDiagram?


#6

If you want to support undo/redo, you need to call Model.removeNodeData or Model.addNodeData.


#7

So, I have to delete the node, modify it, and then add the node?
I am not quite clear about your suggestion. Could you recommend me an example?
By the way, I would like to know whether there is a way to refresh the drawing?


#8

If you want to change some properties of a node data object, call Model.setDataProperty. You don’t need to remove and add it back to the model.

You do need to call Model.addNodeData or removeNodeData if you want to change the contents of the Model.nodeDataArray.

Updating of the diagram will happen automatically at the end of the transaction.

Back to your original question, I was suggesting that you should be iterating over the editable <input> fields to decide what properties to set. The Data Inspector demonstrates this, for example. https://gojs.net/latest/extensions/DataInspector.html