Binding to structured node data

Hello,

Contrary to the GraphLinksModel I have seen in your examples, I have structured node data, like so:

{
<span =“Apple-tab-span” style=“white-space:pre”> key: “1”,
<span =“Apple-tab-span” style=“white-space:pre”> category: “NodeCategory1”,
<span =“Apple-tab-span” style=“white-space:pre”> element: {
<span =“Apple-tab-span” style=“white-space:pre”> name: “Test”,
<span =“Apple-tab-span” style=“white-space:pre”> description: “TestDescription”
<span =“Apple-tab-span” style=“white-space:pre”> },
<span =“Apple-tab-span” style=“white-space:pre”> …
}

But when I try to bind a TextBlock’s text property in a node template to the element.name property in my node data ($(go.TextBlock, new go.Binding(“text”, “element.name”))), there is nothing displayed in that node.

Presumably, it is not possible to bind with an “a.b” notation, although I did not see anything related to this in your documentation.

Would you have any recommendation as to how how could make this work (using a two-way binding especially)? Or is there no choice and the node data to be bound to needs to be flat?

Thanks in advance,
Marc.

You can bind to “element” and use a conversion function. That will work for TwoWay Bindings too, although that isn’t so obvious:

new go.Binding("text", "element", function(e) { return e.text; })
    .makeTwoWay(function(t, data) { data.element.text = t; return data.element; })

If you want to make programmatic changes to the model data, you can do:

var data = myDiagram.model.findNodeDataForKey("1");  // or however you want to get that node data
myDiagram.model.setDataProperty(data.element, "text", "XYZ");
myDiagram.model.updateTargetBindings(data, "element");

Of course the above code needs to be executed inside a transaction, especially if you want to support undo and redo.

I managed to make this work by doing the following:

new go.Binding(“text”, “”, _toName).makeTwoWay(_fromName))

where _toName and _fromName are like so:

function _toName(node) {
return node.element.name;
}

function _fromName(name, node) {
<span =“Apple-tab-span” style=“white-space:pre”> node.element.name = name;
}

Is this the recommended way to do this? I have a feeling there is a performance implication on this, is this the case?

Thanks again,
Marc.

Yes, that should work too.

You are right that using “”, referring to the whole data object, as the source “property” does slow down binding evaluations. Often that doesn’t matter much, but maybe it would if you are updating it continuously and there are a lot of bindings on unrelated bits of state.

Excellent! Thanks very much.