Template load event?

Is there an event that fires when a template is first loaded, similar to the visionWindowOpened() on vision windows?

For context: I’m trying to set default values for the components inside a template that can still be changed by the user. I imagine there might be a better way? :slight_smile:

1 Like

I’m trying to avoid pasting the template components directly in the window container.

Is it possible to access template components through the window somehow? There’s no compatible getComponent() for template holders…

I don’t think there’s anything official, but you can probably take advantage of the propertyChange event function. Looks like property “componentRunning” could be good - I think that only goes true when it starts up. It also goes to false when the template is unloaded, which could be useful.

3 Likes

Thanks, great solution!

mrogers, I think this could solve my problems and I was hoping to get a little more info. When my template repeater loads my propertychange event runs numerous time even though the user has not changed the value. From what you are saying can I check that the componentRunning has gone true before I let the propertychange script run?

I think you are looking for this, add this to your propertyChange event

if event.propertyName == 'componentRunning':
       execute your code

the code will only execute when the componentRunning property is true

2 Likes

I have a template in which I am calling runScript function on the expression of one of the properties by passing other properties as parameters. It gets called multiple times when the window containing the template repeater which loads this template is opened. I am assuming it happens due to other parameters properties changing on window open event.
I think using invokeLater function would resolve this issue, which I am running on componentRunning
propertyChange event but nothing seems to be happening.
I have added same code as above in template’s propertyChange event. Am I missing something?

Edit: I am using Ignition 8.0.12

Can anyone help on this? I need it urgently.

Thanks.

Show your code, and we might be able to help.

@pturmel Thank you for your reply.

Below is my code that I have written on the propertyChange event of the template which I am calling in the template repeater on a window.

if event.propertyName == 'componentRunning':
    print 'Property Changed'
	system.util.invokeLater(func, 500)

Issue is this script is not getting fired, it’s not printing anything.

The “root” of a template is a bit odd. Try placing that on a dummy component inside the template.

Thank you @pturmel for your prompt help.

Actually I put same script on the label component as suggested by you. But while saving I accidentally selected Gateway option on conflict window and basically reverted to old code. But now whenever I open template or window in designer by putting it in preview mode first, I can see the printed message in output console. I am sure I had checked previously also in the same way. But somehow it’s working now.

Thanks again!

I am facing another issue now. I have code like below in template’s propertyChange event

if event.propertyName == 'componentRunning':
     print 'Running'
     def getValues():
          property1 = event.source.property1
          property2 = event.source.property2
          datasetValues = func(property1, property2)
     system.util.invokeLater(getValues, 500)

property1, property2 etc. are internal properties on templates which are bound to OPC, memory tags or is an expression. func is function defined in the package which takes these values and returns a dataset. But I am not getting expected values in returned dataset.

To elaborate more, property2 is an expression tag which looks up for specific value in another dataset property3. So my expression in property2 is
try(lookup({property3}, {property4}, 0, 'lookupColumn', 'resultColumn'), -1)
when I print property2 in getValues function, I get -1. But on template I see the correct value. Since func is being called with wrong values my returned dataset is also wrong.

My understanding is invokeLater allows us to call function after all bindings are evaluated. So it should get the correct values to pass in func

What changes do I need to make in above code?

This is not correct. invokeLater just waits the given number of milliseconds. This can be delayed further if many event scripts are running. It does not wait for asynchronous bindings like tags and queries.

Thanks @pturmel for clearing it. So adding more delay can one of the potential solutions. But this would be uncertain though. May be I will need to read all required values from tags, wherever applicable, on the same componentRunning property change.

No, because that would freeze your UI. Instead, monitor the arrival of the data you need with propertyChange events–when all is present, do the rest of the logic.

@pturmel Thank you for your suggestions. I am reading tag values on propertyChange events. It’s much smoother now.

Do you mean you are monitoring for propertyChange on a property with a tag binding? Or do you mean you are using system.tag.read....() to get the values? If the latter, don’t.

I am checking for propertyChange on a property which has a tag binding.

1 Like

can you expand on this? I have a similar issue.

I have a template repeater and when all the data loads I want a specific values from each template to make a dataset that gets sent to a chart. I can do this manually through a button if I wait for the data to finish updating in the templates, but I want to make this automatic once all the data is done updating.

so when all templates updated get the values from loaded templates and make a dataset.

the number of templates can also change based on the parameters.