I have a recursive object in my Aurelia view model that looks like this:
Class BottomlessPit {
Name: string = '';
MorePits: BottomlessPit[] = null;
}
Therefore, I'd like to use a recursive template in my Aurelia view. It will only be used in one place, so I would rather use a template literal. Here's some pseudocode that doesn't work:
<template name="pit">
<li>
${Name}
<compose view.bind="pit" repeat.for="subpit of MorePits"></compose>
</li>
</template>
Is this a feature of Aurelia?
OK this hurt my head a little bit but here's a way to enable defining inline html-only custom elements...
https://gist.run?id=11ac077048cab0ad9979
app.html
<template>
<h1>Aurelia - Inline Custom Elements</h1>
<template name="person-element" bindable="person">
<h3>${person.name}</h3>
<person-element repeat.for="parent of person.parents" person.bind="parent"></person-element>
</template>
<template name="hello" bindable="message">
${message}
</template>
<person-element person.bind="kid"></person-element>
<hello message="hello world"></hello>
</template>
app.js
export class App {
kid = {
name: 'North West',
parents: [
{
name: 'Kanye West',
parents: []
},
{
name: 'Kim Karsomething',
parents: []
}
]
};
}
main.js
import {relativeToFile} from 'aurelia-path';
import {Origin} from 'aurelia-metadata';
import {TemplateRegistryEntry, TemplateDependency} from 'aurelia-loader';
// override the TemplateRegistryEntry's "template" property, adding
// logic to process inline custom elements (eg <template name="foo">)
let templateDescriptor = Object.getOwnPropertyDescriptor(TemplateRegistryEntry.prototype, 'template');
Object.defineProperty(TemplateRegistryEntry.prototype, 'standardTemplate', templateDescriptor);
Object.defineProperty(TemplateRegistryEntry.prototype, 'template', {
get: function get() {
return this.standardTemplate;
},
set: function set(value) {
// hand off to the standard template property...
this.standardTemplate = value;
let address = this.address;
// loop through each of the inline custom elements and register
// them as dependencies.
let namedTemplates = value.content.querySelectorAll('template[name]:not([name=""])');
for (var i = 0, ii = namedTemplates.length; i < ii; ++i) {
let current = namedTemplates[i];
let name = current.getAttribute('name');
let id = relativeToFile(`./${name}.html`, address); // potential for collision but putting in subfolder would be weird if the inline element had it's own <require> elements
// give the loader the template html
System.set(
id + '!' + System.normalizeSync('text'),
System.newModule({ __useDefault: true, default: current.outerHTML}));
// register the dependency
this.dependencies.push(new TemplateDependency(id, name));
// remove the inline template element from the template
current.parentNode.removeChild(current);
}
}
});
export function configure(aurelia) {
aurelia.use
.standardConfiguration()
.developmentLogging();
aurelia.start().then(() => aurelia.setRoot());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With