I need to centralize event registration, deregistration, and cleanup for my form elements while traversing the tree and managing dependencies. The challenge is ensuring that when an element depends on another by name, it registers and listens to the closest one within its scope—especially when there are multiple elements with the same name, taking Scoped Dependency lookup into account.
I’m thinking about two approaches, but I’m not sure which is best:
I’m looking for ideas on how to best implement this while decoupling these mechanisms, Example:
{
"form": "inventoryForm",
"name": "inventoryForm",
"fields": {
"name": "transactionInfo",
"type": "Section",
"fields": [
{
"name": "transaction",
"type": "SelectOne",
"listName": "transactionTypes"
},
{
"name": "supplier",
"type": "Text",
"rules": [
{
"expression": "#{transaction} == 'supply'",
"action": "Show"
}
]
}
]
}
}
My current approach involves extracting dependencies at runtime using an extension on the FieldTemplate and the Rule:
extension FieldTemplateDependencies on FieldTemplate {
List<String> get dependencies {
List<String> dependencySet = [];
for (final rule in rules) {
final ruleDependencies = rule.dependencies;
dependencySet.addAll(ruleDependencies);
}
return dependencySet.toSet().toList();
}
/// from the choiceFilter expression
List<String> get filterDependencies {
List<String> dependencyList = [];
final fieldPattern = RegExp(r'#\{(.*?)\}');
if (type.isSelectType) {
if (choiceFilter != null) {
final filterDependencies = fieldPattern
.allMatches(choiceFilter!)
.map((match) => match.group(1)!)
.toList();
dependencyList.addAll(filterDependencies);
}
return dependencyList.toSet().toList();
}
return [];
}
String? get evalChoiceFilterExpression =>
choiceFilter?.replaceAll("#{", "").replaceAll("}", "");
}
extension RuleDependencies on Rule {
List<String> get dependencies {
if (expression != null) {
final fieldPattern = RegExp(r'#\{(.*?)\}');
return fieldPattern
.allMatches(expression!)
.map((match) => match.group(1)!)
.toSet()
.toList();
}
return [];
}
String? get evalExpression =>
expression.replaceAll("#{", "").replaceAll("}", "");
}
[”transaction”] it returns [”transactionInfo.transaction”] ← nearest one in supplier path in case another one in another part with the same name exist, it will look recursively and get the nearest and then the field will register as listener for the path and dependency will notify with their paths instead of just the name.Ideas about this page from notion’s AI pot 😃 😋:
October 13, 2024