If this is commented, the text is always persisted.
Notice that we have almost the exact same issue with Node. If you change one of the properties in the node inspector, it will never be persisted, unless you comment :
Before I did the dynamic binding for fromArrow, I only had to set properties that are not used for the actual rendering, such as transitionType, which is specific to my own business requirement.
somehow it makes sense to use model.set but i’m not sure why it is not required for transitionType and becomes mandatory when starting to use the transaction.
I’ve tried to follow this as best as I can, perhaps I can shed some light on the situation.
The inspector should be changing app state, not the GoJS model. When this.diagramLinkData[index] is set to a deep clone of newData, Angular change detection within DiagramComponent notices and updates the GoJS model accordingly.
You probably should not be using any model methods in your handleInspectorChanged function. Instead, just replace the node/link data entry in app data (i.e. diagramLinkData or diagramNodeData), and ensure your Node / Link templates have bindings on the data properties you want to visually depend on these properties.
which will persist the transitionType data property. Then, in your linkTemplate, create a data binding on your arrowhead go.Shape, something like
new go.Binding("fromArrow", "transitionType", (transitionType) => { // do some logic and return a string here }
Please let me know if any of this is not clear. State management with Angular can be a tricky beast. We’re working on an immutable gojs-angular version 2.0, but I can’t promise when it will come out. When it does, it will hopefully make this process more smooth
Interesting. Thanks for this explanations. So if I understand you correctly, I should do something like this :
$(go.Shape, // the arrowhead
new go.Binding('toArrow', 'transitionType', (transitionType) => {
switch (transitionType) {
case 'Linear':
return 'Standard';
default:
return '';
}
}),
),
and in the handleInspectorChange, I roll back to what I had initially :
index = this.diagramLinkData.findIndex(n => n.key === key);
if (index >= 0) {
this.diagramLinkData[index] = _.cloneDeep(newData);
// if shapes appearance should be modified from the inspector, it can be done like this
// this.myDiagramComponent.diagram.model.commit((m) => {
// const link: any = this._processDesignerService.processDesignerMetadata.paletteLinks.find
// ((l: any) => l.transitionType === this.diagramLinkData[index].transitionType);
// if (link) {
// m.set(this.selectedNode.part.data, 'arrowheadFrom', link.arrowheadFrom);
// m.set(this.selectedNode.part.data, 'arrowheadTo', link.arrowheadTo);
// m.set(this.selectedNode.part.data, 'lineType', link.lineType);
// }
// // m.set(this.selectedNode.part.data, 'transitionType', newData.transitionType);
// // m.set(this.selectedNode.part.data, 'transitionRule', newData.transitionRule);
// });
}
}
// here, we set skipsDiagramUpdate to false, since GoJS does not yet have this update
this.skipsDiagramUpdate = false;
I have two problems with that. As you can see in the commented code, I was dynamically setting arrowheadFrom (etc…) based on some value found in this.diagramLinkData. Can I access diagramLinkData from the binding function when creating the link template ?
Second problem is that the function above with the switch is never hit. When I change a value of transiationType in the inspector, the handle function gets hit but not the binding function. Any idea why would that be ?
You should not reference the Angular app-level diagramLinkData in your binding conversion function. But, by the time that conversion function is evaluated, your GoJS Diagram’s Model will be at parity with diagramLinkData, so you could use your the model.linkDataArray for your logic.
I’m surprised your binding function is not evaluating. I just tried with the sample you gave us and it evaluated fine. The entire code for the arrowhead shape in the template I tried is:
$(go.Shape, { toArrow: "OpenTriangle" }, // the arrowhead
new go.Binding('toArrow', 'transitionType', (transitionType, shape) => {
// if you really want access to your diagram's linkDataArray, here's how you could access it
var diagram = shape.part.diagram;
var linkDataArray = diagram.model.linkDataArray; // do whatever logic you need with this
switch (transitionType) {
case 'Linear':
return 'Standard';
default:
return '';
}
})),
Yes it makes perfect sense. Sorry my bad regarding the function not being triggered, I was just doing something silly.
One last thing if you don’t mind. What if in the binding function above, instead of getting the data from linkDataArray, I want to get it from a property provided by an Angular service that is injected in the constructor of my main component. How would I do that ?
I was thinking about using that modelData property of the diagram. Could that hold arrays of lookup data which I could then access from the binding function in my switch statement ? Is this the correct approach ?
Generally, you want your bindings to fire when your a specific node or link model data property changes – it is strange to trigger a binding by changing one piece of data, then rely on some non-model properties. The more pieces of state you depend on for your binding the more careful you’ll have to be about when you update that underlying data property – what if the conversion function evaluates and you haven’t yet updated the other bits of state you want it to depend on?
Accessing Angular app-level properties in binding functions is not recommended – you will likely run into scope issues.
My requirement is to be able to change the appeance of links based on the value in a dropdown of the inspector (tranistionType)
Each transitionType holds values for arrowTo, arrowFrom, dash, stroke etc…
That’s why when the user select a transitionType from the dropdown, I must be able to change the appearnce of the selected link based on the properties of that transitionType.
The transitionType are coming from a service and now I have stored them in dataModel so that they are accessible from the diagram :