Skip to content

Instantly share code, notes, and snippets.

@martonsagi
Last active October 30, 2018 09:15
Show Gist options
  • Save martonsagi/bd1122986ba8dabde8111c3b4ab6df6f to your computer and use it in GitHub Desktop.
Save martonsagi/bd1122986ba8dabde8111c3b4ab6df6f to your computer and use it in GitHub Desktop.
Aurelia - Dynamic components with InlineView
export class Api {
loadTemplate(url) {
return new Promise((resolve, reject) => {
this.callRestApi(url)
.then(result => {
resolve({content: result, error: false});
})
.catch(e => {
console.log(`Could not load template`, e);
let errorMessage =
`<template>Could not load template: ${e.status}. See console (F12) for more information.</template>`;
resolve({content: errorMessage, error: true});
});
});
}
callRestApi(url) {
return new Promise((resolve, reject) => {
let xhr = new window.XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function () {
if(xhr.readyState === 4) {
if (xhr.status === 200) {
resolve(xhr.responseText);
} else {
reject(xhr);
}
}
};
xhr.send();
});
}
}
<template>
<require from="./part"></require>
<part view.bind="testView" model.bind="testModel"></part>
<hr>
<part template-href="./remote-api-result.html"
model.bind="{title: 'Another Title', content: 'Short Content'}"></part>
<hr>
<part template-href="./remote-api-notfound.html" model.bind="testModel"></part>
</template>
import {inject} from 'aurelia-framework';
import {Api} from './api';
@inject(Api)
export class App {
constructor(api) {
this.api = api;
}
attached() {
this.load();
}
load() {
this.api
.loadTemplate('./remote-api-result.html')
.then(result => {
this.testModel = {title: 'Test Title', content: 'Test Content'};
this.testView = result.content;
});
}
}
<template>
<h3><i>${title}</i></h3>
</template>
import { bindable } from 'aurelia-framework';
export class CustomPart {
@bindable title;
}
<!doctype html>
<html>
<head>
<title>Aurelia</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-T8Gy5hrqNKT+hzMclPo118YTQO6cYprQmhrYwIiQ/3axmI1hQomh7Ud2hPOy8SP1" crossorigin="anonymous">
</head>
<body aurelia-app>
<h1>Loading...</h1>
<script src="https://jdanyow.github.io/rjs-bundle/node_modules/requirejs/require.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/config.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/bundles/aurelia.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/bundles/babel.js"></script>
<script>
require(['aurelia-bootstrapper']);
</script>
</body>
</html>
<template>
<compose view.bind="viewStrategy" model.bind="model"></compose>
</template>
import {inject, bindable, InlineViewStrategy} from 'aurelia-framework';
import {Api} from './api';
@inject(Api)
export class Part {
@bindable view;
@bindable model;
@bindable templateHref;
constructor(api) {
this.api = api;
}
viewChanged() {
if (this.view) {
this.viewStrategy = new InlineViewStrategy(this.view);
}
}
templateHrefChanged() {
if (this.templateHref) {
this.api
.loadTemplate(this.templateHref)
.then(result => {
this.view = result.content;
});
}
}
}
<template>
<require from="./custom-part"></require>
<h2>${model.title}</h2>
<custom-part title.bind="model.title"></custom-part>
<p>${model.content}</p>
</template>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment