It seems like you're looking for an inlineView("<your html here/>")
type of functionality for routes so that navigating to the target route will directly render the HTML in the router-view element.
This is not directly possible with aurelia-router because without a ViewModel, no ActivationStrategy can be invoked. Aurelia-router wants to call canActivate
, activate
, canDeactivate
, deactivate
on something.
However, if you simply want to define markup programmatically, and you don't want to declare a ViewModel for each individual piece of markup, then that can be solved quite neatly with the compose
element in combination with inlineViewStrategy
.
With this approach, you only need one View/ViewModel pair which is responsible for retrieving the correct HTML based on the current route, and then render that HTML.
There are also other ways to do this, but AFAIK this approach involves the least amount of plumbing.
Of course you also need an object to store the HTML/route pairs in, and a service to store/retrieve those objects.
You can see a live working version here (including a few comments to clarify things):
https://gist.run/?id=8c7e02ce1ee0e25d966fea33b826fe10
app.js
import { inject } from "aurelia-framework";
import { Router } from "aurelia-router";
import { FaqService } from "./faq-service";
@inject(Router, FaqService)
export class App {
constructor(router, faqService) {
router.configure(config => {
config.map({ route: "", moduleId: "./empty" });
config.map({ route: "faq/:route", moduleId: "./faq-detail" });
});
this.router = router;
this.faqService = faqService;
}
openFaq(item) {
this.router.navigate(`faq/${item.route}`);
}
}
app.html
<template>
<router-view></router-view>
<ul>
<li repeat.for="item of faqService.faqItems" click.delegate="openFaq(item)">
${item.title}
</li>
</ul>
</template>
empty.js (just a convenience for default empty route):
import { inlineView } from "aurelia-framework";
@inlineView("<template>no content</template>")
export class Empty {}
faq-service.js
import { singleton } from "aurelia-framework";
class FaqItem {
constructor(route, title, markup) {
this.route = route;
this.title = title;
this.markup = markup;
}
}
@singleton(false)
export class FaqService {
constructor() {
this.faqItems = [
new FaqItem("question-1", "Question 1", "<h4>Question 1</h4><p>Answer 1</p>"),
new FaqItem("question-2", "Question 2", "<h4>Question 2</h4><p>Answer 2</p>"),
new FaqItem("question-3", "Question 3", "<h4>Question 3</h4><p>Answer 3</p>")
];
}
getByRoute(route) {
return this.faqItems.find(i => i.route === route);
}
}
faq-detail.js
import { inject, InlineViewStrategy } from "aurelia-framework";
import { FaqService } from "./faq-service";
@inject(FaqService)
export class FaqDetail {
constructor(service) {
this.service = service;
}
activate(param) {
let item = this.service.getByRoute(param.route);
this.viewStrategy = new InlineViewStrategy(`<template>${item.markup}</template>`)
}
}
faq-detail.html
<template>
<compose view.bind="viewStrategy"></compose>
</template>