Is it possible to change a node's template after it is created?


I want/need to change a Node’s template based on some properties that might change at runtime…

what I did is:

  • on Model I have:
model.nodeCategoryProperty = 'templateKey';
  • on the object that I use as NodeData I have:
get templateKey(): string { return ...; }
  • when I need to change the template I do:
model.raiseDataChanged(this, 'templateKey', oldTemplateKey, this.templateKey);

I’m pretty sure that the values for template keys are correct when that call is made.
but the Node’s template doesn’t change… :(

any idea about what I’m doing wrong?


you need to call

diagram.model.setCategoryForNodeData(, cat);

See here for an example: GoJS Template Maps -- Northwoods Software


model.setCategoryForNodeData(this, this.templateKey);

doesn’t seem to work in my case… :frowning:

should I maybe make a transaction for each change?.. I’m currently starting a transaction, change a bunch of properties, commit the transaction…

Hmm, hold on.

I want/need to change a Node’s template based on some properties that might change at runtime

What do you mean by this exactly? Do you want to change a bunch of properties on a node, or do you want to change which node template that node is using? I assumed the second, but that might be overkill depending on what you’re trying to do.

If you are just trying to change things like a node’s color, text, etc to be different, arbitrary values at runtime, then you do not need to do any template/category changes. This tutorial on GraphObject manipulation might be a good start for you then. You would just start a transaction, set some properties, and commit the transaction.

If you are trying to make a node look completely different by swapping out its template for another template, then you would want to change its category.

well… both… :smile:

each template has a few bindings for colors, texts and such…

but I also need to be able to change the template of the node…

I had only a model level transaction in my code… and I saw that in that sample there is a diagram level transaction… so added that too…
but it didn’t help… :frowning:

Can you give me an example of what you’re trying to do?

this is my current code:

if (oldTemplateKey != this.templateKey) {
      model.setCategoryForNodeData(this, this.templateKey);

and as far as IE’s debugger says it is sending the right values…

what I’m trying to do is change a node’s template from ‘image’ to ‘text’… I guess I could play with ‘visible’ property on shapes… or to remove and re-add the node on template change… but I would like to have an easier solution…

and as that sample shows… you should be able to change a node’s template… but… not sure why it doesn’t work for me…

is there any logging or something that you can enable for gojs?

ok… I solved the problem… :smile:

if (oldTemplateKey != newTemplateKey) {
     model.setDataProperty(this, 'templateKey', newTemplateKey);

seems the problem was that that property had the new value when I was calling setCategoryForNodeData or raiseDataChanged… and my guess is that internally goJS tested the new value against that and seeing as it is the same did nothing…

btw… that might be considered a bug if you ask me… ;)
because it works in the same scenario for width, height, location, colors etc… just not for templates it seems…

so… if I let goJS set that property for me… it works just fine…


Yes, GoJS property setters are a no-op if the value is the same. Glad it’s solved.

well… the value was the same when I was sending the notification… true…

but the category was different than the current category set on the control…
so maybe it should check with the last set value and not with the current value of the property…

the way I see it… if you 1. change the category and 2. notify goJS about it… it should work… right?

Wait, I misread your code. You should definitely be calling setCategoryForNodeData and not setDataProperty if you want to change the node category. That isn’t working as you’d expect? Would you like me to construct an example?

In your code, what is the value of this? It better be node data (like and not a reference to a node itself.

model.setCategoryForNodeData(this, this.templateKey);

‘this’ is a node data… sure… :smile:

here is an example of it behaving weirdly: Dropbox - Error
just open the html file and click the ‘change’ button a few times…

my problem was kind of similar… couldn’t really reproduce it exactly as my code is much more complex…

So this non-primitive JavaScript object thing looks to be a problem. What are you trying to do with Thingy?

well… Thingy is the object I use for Node Data… and it also holds quite a bit of logic around how to edit nodes and how they behave… so… it kind of has to be there…

anyway… my problem is solved now… so I guess there is no point in continuing this conversation… :)… I only wanted to show you that if you use a more “complex” object as NodeData it might cause weird behaviour… and maybe that raiseDataChanged method should trust me that the data actually changed and update regardless of old/new values test…

A post was split to a new topic: Change node template