Spread operators
Aurelia supports two different spread features in templates:
Bindables spreading: bind multiple properties from an object onto a custom element’s bindable properties.
Attribute transferring: forward captured attributes/bindings from a custom element usage to an element inside its template.
This page focuses on the template syntax and common gotchas. For the deeper conceptual guide, see:
Bindable Properties (Bindables spreading, Attributes Transferring)
1) Bindables spreading
Bindables spreading is for custom element usage. It creates one-way (to-view) bindings from an object’s properties to matching bindable properties on the custom element.
Syntax options
<!-- Recommended: put the expression in the attribute value -->
<user-card ...$bindables="user"></user-card>
<!-- Equivalent: explicit binding command form -->
<user-card $bindables.spread="user"></user-card>
<!-- Shorthand: put the expression in the attribute name (no spaces!) -->
<user-card ...user></user-card>Example
Only keys that match bindable property names (name, email, avatarUrl) create bindings. Extra keys are ignored.
Important gotchas
Keys are property names, not attribute names:
firstNamematches@bindable firstName, butfirst-namedoes not.Shorthand is HTML-case-sensitive in a bad way: HTML lowercases attribute names, so
...firstNamebecomes...firstnameand won’t match your view-model property. Prefer...$bindables="firstName"when case matters.No spaces in shorthand:
...a + bbecomes multiple attributes (...a,+,b) and will not work. Use...$bindables="a + b".Direction is always one-way (
to-view): bindables spreading does not supporttwo-way/from-view. Binding behaviors can’t change direction, but can still affect evaluation (e.g....$bindables="user & debounce:200").Bindings are based on existing keys: if the object did not have a key at the time it was evaluated, no binding is created for that property. To “add” bindings, assign a new object.
Avoid double-binding the same property
You can technically combine spread syntax with explicit bindings, but it creates multiple bindings targeting the same property and can be confusing.
Prefer one approach, or ensure the intent is obvious and well-documented. If you do mix them, the last declared binding typically “wins” at update time.
2) Attribute transferring (...$attrs)
...$attrs)Attribute transferring is for inside a component template: it forwards “captured” attributes and bindings from the component’s usage to an element inside the component.
Minimal example
Enable capturing on the custom element definition:
Use it like a normal input:
Everything that is captured from <form-input ...> will be applied to the inner <input ...$attrs>.
What gets captured?
When capture: true is enabled, Aurelia captures (for later spreading) everything except:
custom element bindables (those are handled as bindables, not captured)
template controllers (like
if,repeat.for,with,portal, etc.)
You can also supply a capture filter function if you only want to capture certain attributes.
Restrictions
You cannot transfer template controllers via
...$attrs(you’ll get a compile error).Don’t overuse deep “pass-through” chains; one or two layers is usually plenty.
Last updated
Was this helpful?