Refresh diagram model from json with Backbone

Hello!
I`m using Backbone model to syncronize data from server. To set diagram model I use diagram.model = go.GraphLinksModel.fromJson(backboneModel.toJSON()).
How can I refresh diagram model when backboneModel changed? If I set from json again, diagram is refreshing, but I need to save diagram state (positions, expanded groups, etc.)

I am guessing that what you are trying to implement is like what is described in https://gojs.net/latest/intro/usingModels.html#ImmutableData

Walter, thank you very much!
It`s work:
model.fetch({
success: function () {
diagram.model.mergeNodeDataArray(model.toJSON().nodeDataArray)
},
})

Since you are using a GraphLinksModel, you need to also set linkKeyProperty on each model and call mergeLinkDataArray.

Now I have another problem. When I start linking tool and deativate it (after mouse down on empty space) old data returns.

As documented at https://gojs.net/latest/api/symbols/Model.html#mergeNodeDataArray that method does not conduct a transaction, so you need to do so in your fetch success function.

If you don’t conduct a transaction when you make changes, the changes will be coalesced into the next transaction. In your case that’s a linking operation which fails, so the linking transaction is rolled back. But in this case that would include what happened before outside of that transaction.

More about transactions is at https://gojs.net/latest/intro/usingModels.html#ModifyingModels and https://gojs.net/latest/intro/transactions.html.

Thanks a lot! This work:
model.fetch({
success: function () {
diagram.startTransaction(“refresh”);
diagram.model.mergeNodeDataArray(model.toJSON().nodeDataArray);
diagram.model.mergeLinkDataArray(model.toJSON().linkDataArray);
diagram.commitTransaction(“refresh”);
},
})

Do you need to call toJSON twice?

It works correct if I change node. When I add node to opened group (whith isOngoing=false) node is showing after I reopen group. How refresh group layout to show new node?
Before re-open
image
After re-open
image

The Group.layout should do that automatically whenever any Node or Link has been added or removed as members of the group. Unless you have explicitly disabled that either on the Layout or on the Part. https://gojs.net/latest/intro/layouts.html#LayoutInvalidation

Group layout:
layout:
$(go.GridLayout,
{
cellSize: new go.Size(1, 1), spacing: new go.Size(4, 4),
wrappingColumn: 2
}),

Group expand event:
subGraphExpandedChanged: function (g) {
g.layout.isOngoing = false;
},

Ah, that explains it.

I tried to set isOngoing = true before transaction and return isOngoing = false after. But it reset positions of all elements. Is it possible to add node with saving positions of other elements?

If I understand your requirements, I think the problem is that all of the predefined layouts such as GridLayout position all of their Nodes whenever the layout is performed, rather than just some of them. It is not a problem of when the layout is invalidated, which is what Layout.isOngoing controls.

I’m curious what the problem is when you allow the Group.layout to operate normally. What exactly is it that you want to support or avoid?

I set isOngoing = false after first group openning to save nodes positions. When I add new node to group, it is’t displaying, becouse isOngoing = false. I solve that problem by setting isOngoing = true before adding, but it reset all nodes positions. I want to save nodes positions after adding new node.

Yes, but why don’t you just set the position of the new node to be where you want it to be, since you seem not to want the Group.layout to do that? That way you would never need to set Group.layout at all, or you could just leave Layout.isOngoing false.

Because I add node not directly to diagram. I save node to server and take new model with that node. I want to set location automatically.

Well, any Group.layout does that automatically, but it will do that for all member Nodes for which Part.isLayoutPositioned is true. But if you set or bind that property to false, the layout will completely ignore such nodes, which I am guessing you also do not want unless you do not mind the new node(s) overlapping old ones.

Thanks, Walter! I will try that.