mergeTemplateAndState method
Sanitizes the properties of a spec
using template
and string evaluation.
E.g.: a property valued "${state.firstName}" will have its value replaced with the state
's "firstName" key value.
Implementation
@protected
void mergeTemplateAndState(
WidgetNodeSpec spec, Map template, Map state, Map parentContext) {
properties.evaluateMap(spec.props, parentContext);
var newTemplate = template.clone();
properties.evaluateMap(newTemplate, parentContext);
// Use Template to set Property values, if not existing
mergeMaps(spec.props, newTemplate);
// Set Widget's value via its alias
var alias = spec.props["alias"] ?? spec.id;
if (state.containsKey(alias)) {
spec.props["value"] = state[alias];
} else if (spec.props.containsKey("value")) {
state[alias] = spec.props["value"];
}
// Evaluate State keys starting with Widget's Id
for (var key in state.keys) {
if (key.startsWith("${spec.id}.")) {
var prop = key.replaceFirst("${spec.id}.", "");
var value = state[key];
dynamic evaluatedValue;
if (value is Map) {
evaluatedValue =
properties.evaluateValue(value.clone(), parentContext);
} else if (value is List<Map>) {
evaluatedValue =
properties.evaluateValue(value.clone(), parentContext);
} else {
evaluatedValue = properties.evaluateValue(value, parentContext);
}
spec.props[prop] = evaluatedValue;
if (value is Map || value is List<Map>) {
// Since we don't know where the key belongs, we'll set it in all Spec Maps
// Only properties should be evaluated in build-time
spec.widgets[prop] = value;
spec.actions[prop] = value;
}
}
}
}