Trigger a refreshBinding('props.data') from inside the module

Hello again,

Is there a way to trigger a this.refreshBinding(‘props.data’) (or something similar) from inside the module?
I would like to implement some sort of refresh button inside my table module. Im guessing its not to hard to trigger a tree.read() through an event, but i doubt this refreshes the binding in ignition…
I would also have to check if there even is a binding on the property i suppose.

Sounds to me you are making your module too specific to a particular UI. That sounds like something you should expose for scripting (methods to call, and event actions for user responses). Let the user tie things together with the designer as they see fit (possibly interposing more actions that just a refresh).

yes kinda, but i can use an extension function in order to overwrite the "refresh" if its required.
But (unfortunalty) extension function are by default disabled so i need to do something else if its not enabled.

Its quite the complex component with tons of features xd And a refresh button is something that sounds usefull all the time so i would like to not have to bind a button or timer on every table i use xd
i can easily put it in the context menu that shouldnt really mess with any UI.

here i explained a tiny bit and have some screens of what my component all can do so far

@PGriffith any idea?

I don’t really understand why you’d want to trigger a specific binding from the backend.

It seems like your component is trying to do a bit too much at one time. Again, I still don’t really understand all of what you’re trying to get to, but it seems like you want the data to be totally dynamic. That’s a laudable goal, but if that’s the case, then it’s a bit of an anti-pattern to programmatically refresh it. You may know better than your users when to refresh, but usually we try to make ‘display’ components (table, standard charts, dropdowns, etc) data-agnostic, so to speak. They ‘just’ display whatever data they’re fed from their own bindings, and it’s up to the designer to add in programmatic refreshes.

On the other end of things, you’ve got ‘bespoke’ components, like the alarm status table. Here, you’re by definition always going to be querying one specific area - so you just expose your filters and tuning knobs and whatever else to the user via properties.

It seems like you’re trying to make a component that’s data-agnostic, but also “knows” when to refresh itself, which seems like a contradiction to me.

I don’t really know what you’re trying to do, so I’m not trying to say that there’s no way what you’re doing makes sense - you know your problem better than I do, obviously. But I do wonder if there’s not a better way, from ‘first principles’, to set up this component.

2 Likes

Yes i understand. But some of our tables have quite big querries, so we dont want to refresh them automatically to often through the binding.
But if they know something new came in, that they need to check right now it could be nice to have the refresh button handy.
And ofc the designer can do that on the view itself, but we use this component in a lot of views, and I thought its a usefull enough feature to just include in the modules custom context menu.

Are there better ways? maybe, but i havent really thought about it, as this one seemed good enough at the time.

I can’t see building the query into the module, either, unless its the module’s reason for existence. (For a single module, try to do one thing well. Or a group of closely related things.) Let the designer tie stuff together with platform-standard techniques.

im not building the query in the module. the query is bound to a property “data” just like normal.
it is this binding i want to refresh tho.

Well, under the assumption you know better than us :), the good news is it appears to be pretty trivial to trigger a refreshBinding yourself:

var property = PropertyKey.fromString(propertyStr);
var result = component.getSession().queue().runOrSubmit(() -> component.refreshBinding(property));

Nah i definitly dont, i dont even know what the words "data-agnostic" and "bespoke" mean xD.
So i'll add in a prop to turn off this feature by default, that way if someone wants to turn it on they can.

i'll test it out once i have some time, im glad it looks quite easy to do.

Seems its not as easy afterall xd component.refreshBinding(property) does not work.
The refreshBinding seems to be located in class ComponentModel, while the component in the delegate is just Component.
Is it possible to get the ComponentModel ?

Weird there is no findComponentByAddressPath as you can get the AddressPath on both Component and ComponentModel

Hm, it should be safe to cast the Component you get inside your delegate to a ComponentModel. We could probably promote refreshBinding to the interface, but I don’t really see this architecture changing out from under you.

1 Like

Nice it works :smiley:

var property = PropertyKey.fromString("props.data");
var result = component.getSession().queue().runOrSubmit(() -> ((ComponentModel)component).refreshBinding(property));

I’m trying to do something similar. Currently, I’m able to trigger the refreshBinding of a table from a button on click event. I would like to trigger the refreshBinding for the table when the data changes on a tag value. How would you reference the table component for a tag change event?

Thanks

You don’t. Tags, themselves, have no access to anything in your user interfaces.

Instead, create a custom property on the table (or somewhere in the view) and bind the tag to that property. Then add an onChange action to that property that calls refreshBinding.

Phil,

Thank you very much for your help!

Initially, I had tried binding the tag to a label, but the label does not have an on change event.

Your suggestion worked!