Aurelia Dynamic Composition

One of my favourites parts of Aurelia is the compose element which allows you to dynamically render UI into the DOM. It is especially handy in situations where you want to dynamically render ViewModels inside of a loop like widgets or other dynamically composed elements.

Containerless

One of the lesser known features of the compose element is the ability to specify a containerless attribute on the element. By default if you use the compose element your page will feature the element with the rendered contents inside.

Sometimes you don’t want the compose element just the contents rendered inside because you might be using it to render table rows or parts in the DOM where the compose element would break the layout.

This would render the contents of the composed view minus the compose element, cool huh?

ViewModel-less

Sometimes you might just want to render a HTML View and not concerned with ViewModel data. Using the view attribute we can render custom views without needing to specify anything else.

In the below example if the widget type property is “table” then the view loaded would be: table-view.html – as you can see we can dynamically compose views without needing to pass in a ViewModel. This means the composed elements becomes databound to the surrounding context which is embedding the element.

Supply data via view-model to

What good would being able to render custom components into your DOM be if you couldn’t pass in data as well? Using the model attribute we can pass in an object of data which becomes available in the ViewModel of our composed View.

Assuming our widget objects have a data attribute which has an object of data, we can specify our compose element passes through this data so it can be used within the view. You can also pass through a Javascript class filename to view-model which allows you to use lifecycle methods like activate (which gets the data as its first argument as an object) inside of your ViewModel.

Accessing model.bind data

To get data passed through to a element, you can specify a canActivate or activate method inside of your viewmodel and the first parameter gives you the supplied model.

export class MyViewModel {
    activate(model) {
        // model is the passed through object
    }
}

Conclusion

We are only scratching the surface here. If you want more information on using compose to suit your needs, feel free to leave a comment for more advice and usage examples.