Embedded view: binding updates even when unrelated parameter changes

Hello everyone,

I’m asking for help with a strange behavior I’m experiencing when using an embedded view.

I have two custom properties in the view:

  • ds (dataset)

  • key (text)

I simply pass these two properties to the parameters of the embedded view.

Inside the embedded view, I have a simple text field with an expression binding like this:

coalesce(try({view.params.ds}[0, "label"], ""), "")

where "label" is the name of the dataset column.

Up to this point, everything works fine — the value from the dataset is correctly loaded into the text field. Now I’ll describe the issue step by step.

  1. The text field binding loads the value from the dataset column, for example "M_L".

  2. The user edits the text field to "G_O", and the value is correctly changed without being overwritten.

  3. Then, the user modifies the key custom property.

  4. What happens is that the text field’s expression binding is re-executed, causing it to reload the value from the dataset — so the text field value goes back to "M_L".

I’d like to understand if it’s normal for the binding to re-evaluate every time a parameter is updated, even if that parameter is not directly linked to the binding itself.

Thanks for the help.

I assume the text field value is bound to key? If so, make sure the binding has bidirectional checked.

It is not, this is the point, text field is bound with this expression:

coalesce(try({view.params.ds}[0, "label"], ""), "")

key is simply passed as a parameter to the embedded view, and within that view it has no binding at all. So I don’t understand why the expression binding re-evaluate when the value of key change.

I think you're seeing this because you're using a dataset as a parameter.

Datasets aren't really first class objects in Perspective, and I'd bet there is something lossy in the Gateway -> Client -> Gateway sync process that's causing spurious change events to be detected for datasets.

It's worth noting that this issue doesn't happen with my Embedded View + component, so I'd wager that these extra change detections are coming from the Perspective client side of things.

Thanks for the answer @bmusson.

I ran a test, changing the query's return type from dataset to json and modifying the text field's expression binding to coalesce( try( {view.params.ds}[0]['label'], ""), ""). Now the problem doesn't seem to occur anymore.

So, given that I need to use JSON, I'm facing another issue. Initially, my expression binding used the lookup() function to find a specific value in the "ZST_CODPAR" column and extract the data from the "VAL_PAR" column:

coalesce( try( lookup( {view.params.dati_ricerca.ds_scheda_lavoro}, {this.custom.specifico}, "", "ZST_CODPAR", "VAL_PAR" ), ""), "")

Now that the return is JSON and not a dataset, I can no longer use lookup(). What would be the best solution to access this data? I would like to avoid using runScript() or a script transform.

Here is the JSON, for example:

JSON

[
  {
    "ZST_CODPAR": "VAL_0",
    "VAL_PAR": "45"
  },
  {
    "ZST_CODPAR": "VAL_1",
    "VAL_PAR": "45"
  }
]

I'll also take this opportunity to ask where I can download the module you mentioned. I followed the link, but it took me to the version for Ignition 8.3, I’m using the 8.1.

Thank you.

For the time being, I've "resolved" it as follows:

  1. I retrieve the data using a Named Query, setting its return format to JSON instead of dataset.

  2. I pass the JSON as a parameter to the Embedded View.

  3. In the Embedded View, I created a custom property ds, bound it to the incoming JSON params, and used a script transform to convert it back into a dataset.

  4. I set the text field bindings as they were originally, but pointing to this new custom property instead of the view's params.

This way, the data is not overwritten.

If you have my Integration Toolkit, you can use the where() expression function and then square bracket operations to do the equivalent of lookup() with lists of dictionaries. Perhaps this:

coalesce(
    try(
        where(
            {view.params.dati_ricerca.ds_scheda_lavoro},
            it()["ZST_CODPAR"] = {this.custom.specifico}
        )[0]["VAL_PAR"]
        ""
    ),
    ""
)
2 Likes

@pturmel, I’ve installed it and make it works with your code, thanks for the suggestion, so I removed the double passage with the script transform.

PS: for completeness, in case anyone needs it, the comma after

"]" is missing

)[0]["VAL_PAR"],

2 Likes

Anytime that you can use an expression over script transforms, especially with Phil’s toolkit, it’s a huge performance win.

2 Likes