The flexibility of Aurelia means there are many ways to achieve a task. The default convention of view/view-model will meet your needs a lot of the time, but sometimes you might need a little more power.
You might already know of the ability to define views inline (inside of your view-models) using the inlineView
decorator, allowing you to eschew view HTML files entirely. The InlineViewStrategy
class offers similar functionality for a different purpose.
Using the below approach, we can render views dynamically from strings. If your server returns HTML to be rendered for example, then you can take this and use it to create a view.
The first argument of InlineViewstrategy
accepts your HTML string, which needs to be wrapped in opening and closing template tags <template></template>
. There is an optional second argument where you can pass through one or more dependencies in an array.
import {InlineViewStrategy} from 'aurelia-framework';
export class MyDynamic {
constructor() {
this.viewStrategy = null;
this.someVar = 'a value inside of it.';
}
bind(bindingContext, overrideContext) {
this.viewStrategy = new InlineViewStrategy(`<template>This is my string with ${someVar}</template>`);
}
}
<template>
<compose view.bind="viewStrategy"></compose>
</template>
The above code could be modified to allow for the view to be updated after initial rendering, as view.bind
will see changes made to the viewStrategy
variable and re-render accordingly.
Because we are using <compose></compose>
without supplying a view-model, the current view-model will be used as the context, allowing us to just specify our own view and keep everything else as intended.
If you don’t want that <compose>
element uglying up your beautiful HTML markup you can use the containerless attribute like this:
<template>
<compose containerless view.bind="viewStrategy"></compose>
</template>
In many cases, the above is for pretty niche scenarios. There are definitely easier ways to achieve most tasks, with additional power there (as shown above) to take control if you need it.
Great! Do we have reference code for this?
I’m looking to create micro frontends (https://www.thoughtworks.com/radar/techniques/micro-frontends) and this is something that would help.
So, could something like this be used to just simply bind a ViewModel to a section of HTML already being output in a CSHTML file (ASP.NET)? I want to completely bypass all “.html” file templates and ONLY use them when necessary (e.g. re-usable components).
@TimMc
Terribly sorry about the reply, yes you could absolutely do that. Because we are using the compose element, you can pass in a view-model of your choosing which the HTML is bound to.