Sorry to resurrect a dead thread, but we're debugging some bad behavior on our project and have tracked it down to what we think is this issue.
In one view, we have a button that calls a script like this:
system.perspective.openPopup(
'AirQTile-settings',
'RangerTiles/Settings/AirQSettings',
params={
'field_name': self.view.custom.field_name,
'node_reference': self.view.custom.node_reference,
},
showCloseIcon=False,
modal=True,
overlayDismiss=True,
draggable=False,
resizable=False,
viewportBound=True,
)
Then, in the popup view, we have inputBehavior
set to "replace", and a property bound to an expression of the two parameters like this:
In the browser debug console, I see one or more prints every time I open the popup. If there's only one, both parameters will have the proper values. If there's more than one, the extra prints will have null for one or both of the parameters. On occasion, the extra prints with nulls are shown last, and I have evidence that the binding is also calculating with those bad values last.
I could refuse to run most of the work when the binding is triggered with a null input, but it has to return SOMETHING into the property it is setup on.
So, I guess these are my questions:
- Is there some way to not have the binding trigger with the NULL parameters?
- Is there some way to have a binding not change the value it is setup on and just leave it as it was before the binding triggered?
(On Ignition 8.1.42)
UPDATE:
It occurred to me that I could achieve #2 in my questions by just making a dummy property which is bound to the expression structure and optionally writes to the real property that the binding used to be on in a script.
Further, I realized I could do everything in an onChange
script of that dummy property instead of a binding transform. Trivial difference, except that it lets me see previous and current values, and all of them as qualified values.
So, I setup a new property with the same expression structure binding as above, but no transform script, and then put an onChange script on it that looks like this:
def valueChanged(self, previousValue, currentValue, origin, missedEvents):
system.perspective.print(u'previous={}'.format(previousValue))
system.perspective.print(u'current={}'.format(currentValue))
# ... lots of other script work here ...
self.custom.original_property = what_the_script_used_to_return_in_the_original_binding
And I then open/closed the popup over and over and I still get the duplicate prints in some openings.
When I get the duplicate triggers, I saw this in the console:
previous=None PerspectiveClient.4c66478bafda3caeebe1.js:2:473641
current=QV[{node_reference=[demo/353785720527380, Good_Unspecified, Thu Oct 24 16:33:01 UTC 2024 (1729787581240)], field_name=[null, Uncertain_InitialValue, Thu Oct 24 15:06:46 UTC 2024 (1729782406021)]}, Good, Thu Oct 24 16:33:01 UTC 2024] PerspectiveClient.4c66478bafda3caeebe1.js:2:473641
previous=QV[{node_reference=[demo/353785720527380, Good_Unspecified, Thu Oct 24 16:33:01 UTC 2024 (1729787581240)], field_name=[null, Uncertain_InitialValue, Thu Oct 24 15:06:46 UTC 2024 (1729782406021)]}, Good, Thu Oct 24 16:33:01 UTC 2024] PerspectiveClient.4c66478bafda3caeebe1.js:2:473641
current=QV[{node_reference=[demo/353785720527380, Good_Unspecified, Thu Oct 24 16:33:01 UTC 2024 (1729787581240)], field_name=[DEVAIRQ, Good_Unspecified, Thu Oct 24 16:33:01 UTC 2024 (1729787581240)]}, Good, Thu Oct 24 16:33:01 UTC 2024] PerspectiveClient.4c66478bafda3caeebe1.js:2:473641
So, it looks like the "Wait on All" is still allowing Uncertain_InitialValue through in this case...
At this stage, I can just filter them out on my own, but I feel like it might be a bug that I have to with "Wait On All" enabled.
UPDATE2:
Our final onChange script looks like this:
def valueChanged(self, previousValue, currentValue, origin, missedEvents):
VALUE_FIELDS = ('node_reference','field_name')
if not currentValue.getQuality().isGood():
return
value = currentValue.getValue()
if any((vf not in value or str(value[vf].getQuality()) == 'Uncertain_InitialValue') for vf in VALUE_FIELDS):
return
# Everything that used to be accessed as "value.field_name" in the old binding script is now accessible like "value['field_name'].getValue()"
# ... Remainder of original binding script goes down here ...
With this tweak in place, I have not been able to get our bad behavior that I was debugging to happen again.
Again, I feel like this is exactly what the "Wait On All" was supposed to be preventing. Did I misunderstand how it worked or is this a bug?