Dependencies
Dependencies is the data context a fragment is inflated with. It holds the values,
objects, and functions that EL expressions read — when a fragment renders
${user.email}, it's reading user.email from its Dependencies instance.
Controllers write into it; fragments read from it. See
State and Reactivity for how those reads become
live-updating UI.
Reading and Writing
setValue and getValue address nested data with dot and bracket paths. Writing
creates any intermediate collections that don't exist yet; reading a path that
doesn't exist returns null instead of throwing.
final dependencies = Dependencies();
dependencies.setValue("users[0].name", "Maya Chen");
dependencies.setValue("users[0].email", "[email protected]");
print(dependencies.getValue("users[0].name")); // Maya Chen
print(dependencies.getValue("users[3].email")); // null — no error
The constructor accepts the same path-keyed map:
final dependencies = Dependencies({
"users[0].name": "Maya Chen",
"users[0].email": "[email protected]",
});
Fragments read the same structure through EL:
<forEach var="user" items="${users}">
<Row>
<Text data="${user.name}"/>
<Text data="${user.email}"/>
</Row>
</forEach>
Note
The index operators dependencies["key"] and dependencies["key"] = value are
plain map access — they treat the key as a single literal string. Use
setValue/getValue when you want dot/bracket paths.
Global Data
Prefixing a path with global. stores the value in a single store shared by every
Dependencies instance in the app, for its entire lifetime. Use it for app-wide
state — the signed-in user, session settings — and keep everything else local, so
one screen's data can't leak into another.
Any fragment can read it, whatever Dependencies instance it was inflated with:
Functions
Dependencies hold functions the same way they hold data. Controllers bind callbacks
in bindDependencies(), and fragments invoke them — bound directly to a widget
attribute, or called with arguments through a <callback>
tag.
See Controllers for the full pattern.
Reacting to Changes
listenForChanges returns a ValueNotifier for a path. Writes that go through that
path update the notifier, which is what the <ValueListener>
component uses to rebuild its children:
dependencies.setValue("user.email", "[email protected]"); // ValueListener rebuilds
The rules for which writes notify which listeners have real subtlety — writes through a path notify, writes below one may not. Read State and Reactivity before relying on them.
Scoping
Every fragment inflation receives a Dependencies instance, but not necessarily a
new one. The <fragment> tag's dependenciesScope attribute controls whether a
child fragment shares its parent's instance (inherit), gets a snapshot (copy),
or starts empty (new) — and which one is the automatic default. That behavior is
owned by Fragments; the summary that matters here:
global. data ignores scoping entirely, and everything else follows it.
API Summary
| Member | Behavior |
|---|---|
Dependencies([data]) |
Creates an instance, applying addAll(data) when provided |
setValue(path, value) |
Writes a value; creates missing intermediate collections |
getValue(path) |
Reads a value; returns null for missing paths |
removeValue(path) |
Removes and returns a value |
addAll(map) |
Applies a map of path/value pairs via setValue |
putIfAbsent(key, value) |
Writes only when the key has no value yet |
listenForChanges(path, [initialValue, defaultValue]) |
Returns the path's ValueNotifier, creating it if needed |
copy({addData, preserveData}) |
Shallow copy — the mechanism behind copy scoping |
[key] / [key] = value |
Plain map access; no path resolution |
All path-accepting members understand the global. prefix.