Controling bindings evaluation order

Try this:

View JSON
{
  "custom": {
    "isFresh": true
  },
  "params": {
    "category_id": "",
    "family_id": "",
    "item_id": ""
  },
  "propConfig": {
    "custom.isFresh": {
      "access": "PRIVATE",
      "binding": {
        "config": {
          "expression": "coalesce({view.params.family_id}, {view.params.category_id}, {view.params.item_id})"
        },
        "transforms": [
          {
            "expression": "true",
            "type": "expression"
          }
        ],
        "type": "expr"
      },
      "persistent": true
    },
    "params.category_id": {
      "paramDirection": "input",
      "persistent": true
    },
    "params.family_id": {
      "paramDirection": "input",
      "persistent": true
    },
    "params.item_id": {
      "onChange": {
        "enabled": null,
        "script": "\tself.getChild(\"root\").getChild(\"families\").getChild(\"Dropdown\").props.value \u003d self.params.family_id\n\tself.getChild(\"root\").getChild(\"categories\").getChild(\"Dropdown\").props.value \u003d self.params.category_id\n\tself.getChild(\"root\").getChild(\"items\").getChild(\"Dropdown\").props.value \u003d self.params.item_id"
      },
      "paramDirection": "input",
      "persistent": true
    }
  },
  "props": {},
  "root": {
    "children": [
      {
        "children": [
          {
            "events": {
              "component": {
                "onActionPerformed": {
                  "config": {
                    "params": {},
                    "view": "Pascal2"
                  },
                  "scope": "C",
                  "type": "nav"
                }
              }
            },
            "meta": {
              "name": "Button"
            },
            "position": {
              "basis": "80px"
            },
            "props": {
              "text": "Return"
            },
            "type": "ia.input.button"
          },
          {
            "meta": {
              "name": "Label"
            },
            "position": {
              "basis": "100px"
            },
            "propConfig": {
              "props.text": {
                "binding": {
                  "config": {
                    "path": "view.custom.isFresh"
                  },
                  "type": "property"
                }
              }
            },
            "type": "ia.display.label"
          }
        ],
        "meta": {
          "name": "return"
        },
        "position": {
          "basis": "50px"
        },
        "type": "ia.container.flex"
      },
      {
        "children": [
          {
            "meta": {
              "name": "Label"
            },
            "position": {
              "basis": "150px"
            },
            "props": {
              "text": "families"
            },
            "type": "ia.display.label"
          },
          {
            "meta": {
              "name": "Dropdown"
            },
            "position": {
              "basis": "256px"
            },
            "propConfig": {
              "props.options": {
                "binding": {
                  "config": {
                    "queryPath": "sandbox/list_families"
                  },
                  "type": "query"
                }
              },
              "props.value": {
                "binding": {
                  "config": {
                    "expression": "if(true, {view.params.family_id}, {this.props.options})"
                  },
                  "transforms": [
                    {
                      "code": "\treturn value if self.view.custom.isFresh else None",
                      "type": "script"
                    }
                  ],
                  "type": "expr"
                },
                "onChange": {
                  "enabled": null,
                  "script": "\tif origin \u003d\u003d \u0027Browser\u0027:\n\t\tself.view.custom.isFresh \u003d False"
                }
              }
            },
            "props": {
              "showClearIcon": true
            },
            "type": "ia.input.dropdown"
          },
          {
            "meta": {
              "name": "value"
            },
            "position": {
              "basis": "150px"
            },
            "propConfig": {
              "props.text": {
                "binding": {
                  "config": {
                    "path": "../Dropdown.props.value"
                  },
                  "type": "property"
                }
              }
            },
            "type": "ia.display.label"
          }
        ],
        "meta": {
          "name": "families"
        },
        "position": {
          "basis": "34px"
        },
        "props": {
          "style": {
            "gap": "3px"
          }
        },
        "type": "ia.container.flex"
      },
      {
        "children": [
          {
            "meta": {
              "name": "Label"
            },
            "position": {
              "basis": "150px"
            },
            "props": {
              "text": "categories"
            },
            "type": "ia.display.label"
          },
          {
            "meta": {
              "name": "Dropdown"
            },
            "position": {
              "basis": "256px"
            },
            "propConfig": {
              "props.options": {
                "binding": {
                  "config": {
                    "parameters": {
                      "family_id": "{.../families/Dropdown.props.value}"
                    },
                    "queryPath": "sandbox/list_categories"
                  },
                  "type": "query"
                }
              },
              "props.value": {
                "binding": {
                  "config": {
                    "expression": "if(true, {view.params.category_id}, {this.props.options})"
                  },
                  "transforms": [
                    {
                      "code": "\treturn value if self.view.custom.isFresh else None",
                      "type": "script"
                    }
                  ],
                  "type": "expr"
                },
                "onChange": {
                  "enabled": null,
                  "script": "\tif origin \u003d\u003d \u0027Browser\u0027:\n\t\tself.view.custom.isFresh \u003d False"
                }
              }
            },
            "props": {
              "showClearIcon": true
            },
            "type": "ia.input.dropdown"
          },
          {
            "meta": {
              "name": "value"
            },
            "position": {
              "basis": "150px"
            },
            "propConfig": {
              "props.text": {
                "binding": {
                  "config": {
                    "path": "../Dropdown.props.value"
                  },
                  "type": "property"
                }
              }
            },
            "type": "ia.display.label"
          }
        ],
        "meta": {
          "name": "categories"
        },
        "position": {
          "basis": "34px"
        },
        "props": {
          "style": {
            "gap": "3px"
          }
        },
        "type": "ia.container.flex"
      },
      {
        "children": [
          {
            "meta": {
              "name": "Label"
            },
            "position": {
              "basis": "150px"
            },
            "props": {
              "text": "items"
            },
            "type": "ia.display.label"
          },
          {
            "meta": {
              "name": "Dropdown"
            },
            "position": {
              "basis": "256px"
            },
            "propConfig": {
              "props.options": {
                "binding": {
                  "config": {
                    "parameters": {
                      "category_id": "{.../categories/Dropdown.props.value}"
                    },
                    "queryPath": "sandbox/list_items"
                  },
                  "type": "query"
                }
              },
              "props.value": {
                "binding": {
                  "config": {
                    "expression": "if(true, {view.params.item_id}, {this.props.options})"
                  },
                  "transforms": [
                    {
                      "code": "\treturn value if self.view.custom.isFresh else None",
                      "type": "script"
                    }
                  ],
                  "type": "expr"
                },
                "onChange": {
                  "enabled": null,
                  "script": "\tif origin \u003d\u003d \u0027Browser\u0027:\n\t\tself.view.custom.isFresh \u003d False"
                }
              }
            },
            "props": {
              "showClearIcon": true
            },
            "type": "ia.input.dropdown"
          },
          {
            "meta": {
              "name": "value"
            },
            "position": {
              "basis": "150px"
            },
            "propConfig": {
              "props.text": {
                "binding": {
                  "config": {
                    "path": "../Dropdown.props.value"
                  },
                  "type": "property"
                }
              }
            },
            "type": "ia.display.label"
          }
        ],
        "meta": {
          "name": "items"
        },
        "position": {
          "basis": "34px"
        },
        "props": {
          "style": {
            "gap": "3px"
          }
        },
        "type": "ia.container.flex"
      }
    ],
    "meta": {
      "name": "root"
    },
    "props": {
      "direction": "column",
      "style": {
        "gap": "10px",
        "padding": "15px"
      }
    },
    "type": "ia.container.flex"
  }
}

The only scripts are very simple transforms that check the semaphore. The use of coalesce() with the custom.isFresh view property is solely to have something that will respond to parameter changes.

Similarly, the if(true, ...) expressions for the dropdowns' props.value is there purely to monitor changes to the options.

{ You'll have to reset the nav target to the your real project's view name. }

1 Like