Dynamic composition
Aurelia's dynamic composition enables you to render a view/view model pair—or just a view—dynamically at runtime. With <au-compose>
, you can:
Render any custom element by binding its definition to the
component
property.Render plain HTML templates.
Dynamically swap components based on user state or configuration.
Access lifecycle hooks (including an extra
activate
method) on the composed view model.
Basic Composition
To render a custom element using its component definition, bind the element to <au-compose>
:
In your view model, define the component with a custom element definition:
Info: When a custom element is used, all standard lifecycle events (including
activate
) will be invoked.
Composition with a String Component
If you pass a string to the component
property, Aurelia treats it as the name of a custom element and performs a lookup. For example:
If my-input
is registered globally, the lookup will succeed; otherwise, an error is thrown if no matching element definition is found.
Composing Without a Custom Element
Dynamic composition isn’t limited to custom elements. You can compose a view only or combine a simple view model (plain object) with a view.
Template-Only Composition
Render a simple HTML template:
Here, Aurelia processes the HTML string with its template compiler and renders it in place.
Combining Template and Literal Object
You can supply both a view (template) and a literal object as the component:
Note: When composing without a custom element as the view model, the composed component will by default use the parent scope—unless you override it using
scope-behavior
.
Customized Host Element
By default, composing a custom element creates a host element based on the element’s name (e.g. <my-input>
). For non-custom element compositions, Aurelia inserts a comment boundary:
Renders as:
To wrap the composed content in a real HTML element, use the tag
bindable property:
Renders as:
Bindings declared on <au-compose>
will be transferred to the new host element.
Passing Data with model.bind
model.bind
The model
bindable lets you pass data into the composed view model. When the model
changes, the activate
method of the composed view model is called with the new value.
Example – Passing a View Model
Or, pass an inline object:
In the composed component:
When to Use Dynamic Composition
Dynamic composition is best suited for scenarios where standard custom element usage may be too rigid. Consider using <au-compose>
when:
Scenario
Why Use Dynamic Composition
Dynamic Content Based on User Input or State
To render different views or components on the fly (e.g., dashboards, conditional widgets).
Rendering Unknown Components at Runtime
In plugin-based architectures, where components are not known at compile time.
Conditional Rendering of Multiple Views
Instead of complex if.bind
or switch statements, use a single dynamic composition point.
Complex Reusable Layouts
To inject varying content into consistent layouts, promoting reusability and DRY code.
Simplifying Component Interfaces
To encapsulate multiple parameters in a model object, avoiding overly complex interfaces.
Decoupling Component Logic
To separate the decision of what to render from the rendering logic itself.
Lazy Loading to Reduce Initial Load Time
To load components only when needed, improving performance in large, single-page applications.
Accessing the Composed View Model
Sometimes you need a reference to the view model of the composed component. Use the component.ref
binding to capture it:
This works similarly to view-model.ref
in Aurelia 1, giving you programmatic access to the instance.
Passing Props Through to the Composed Component
Bindings declared on <au-compose>
are automatically passed to the composed view model (if it is a custom element). For example:
Assuming the following component definition:
This works as if you had written in app.html
:
Migrating from Aurelia 1 <compose>
<compose>
Dynamic composition in Aurelia 2 differs from Aurelia 1. Key changes include:
Template and Component Property Renames
Aurelia 1:
view.bind
andview-model.bind
Aurelia 2: Use
template.bind
andcomponent.bind
String Values
Passing a string now only works for custom element names. A string passed to
template
is interpreted as literal HTML.
Scope Inheritance
By default, when composing a view only or a plain object, the parent scope is inherited. To disable this, set the
scope-behavior
attribute:
Bindings Transfer
All bindings on
<au-compose>
are now transferred to the composed custom element’s view model. Thus,component.ref
now returns the view model, not the composer itself.
Dynamic Module Loading
If you need to load a module dynamically for the view, use a value converter:
This value converter fetches the template from a URL and returns its text.
Last updated
Was this helpful?