问题
I need to create a multilevel navigation menu. The contents of the menu vary depending on the user. I plan on pulling the collection of navigation items that can contain an array of child items via a service that will return the data as JSON. Every example of navigation/routing I've seen uses static routes or single level menus. I have read a bit about child routing but that does not seem to be what I need. The only thing I can think of is to create a custom navigation element who's model will register the routes in a plain array using the data in the navigation items collection. I would then use this collection to render the HTML instead of using router as it contains the hierarchical information. Is there an easier way to do this. This is the first JS framework I have worked with so I'm trying to get up to speed.
回答1:
This is fairly easy, actually. You'll just add a property to the route's settings
object. You can name it whatever you want. It'll have a collection of menu items for the sub menu. Just use that to build the sub-menu.
Here's an example: https://gist.run?id=beb5ba9155fdb2ccefcf78676879b1ca
app.html
<template>
<ul>
<li repeat.for="row of router.navigation" class="${row.isActive ? 'active' : ''}">
<a href.bind="row.href">${row.title}</a>
<ul>
<li repeat.for="sub of row.settings.subRoutes">
<a route-href="route.bind: row.config.name; params.bind: sub.params">${sub.name}</a>
</li>
</ul>
</li>
</ul>
<div class="page-host">
<router-view></router-view>
</div>
</template>
app.js
import {activationStrategy} from 'aurelia-router';
export class App {
configureRouter(config, router) {
config.title = 'Aurelia';
config.map([
{
route: ['', 'one'],
name: 'one',
moduleId: 'one',
nav: true,
title: 'Page 1',
activationStrategy: activationStrategy.invokeLifecycle,
settings: {
subRoutes: [
{
name: 'Sub-choice 1',
params: {
'foo': 'bar'
}
},
{
name: 'Sub-choice 2',
params: {
'foo': 'two'
}
}
]
}
},
{ route: 'two', name: 'two', moduleId: 'two', nav: true, title: 'Page 2' }
]);
this.router = router;
}
}
one.html
<template>
Page One<br />
Params:<br />
<pre><code>${params}</code></pre>
</template>
one.js
export class One {
activate(params) {
this.params = JSON.stringify(params);
}
}
The parameters you pass can be anything you like. For example, they could be the information on what route the should be activated on a child router on the route you're going to. You could call router.navigate...
in the activate method of the page (one.js
in the example below) to navigate to the correct route on the child router. You really can do whatever you want, since you can put any old thing you'd like on that settings object.
回答2:
I have solved similar problem in following way:
- I have simple navigation tree retrieved from the server
- Then I walk the tree and convert all the navigation items to the aurelia routes, actually flatten tree to array, so every route will have settings property like:
{id: 2, parentId: 1, level: 1}
at that moment - Then I pass this flat array to
config.map()
and create a new tree object using items fromrouter.navigation
(remember: I savedid
andparentId
insettings
) onrouter.ensureConfigured().then(_ => {createNavTree(router.navigation)})
- Use output from
createNavTree(...)
to render list items. (level
is used just for some styling) - So in general I create flat
router.navigation
array and use its items to create own tree structure to render the navigation
Also I listen for changes in router.currentInstruction
to track menu collapsing when subitem is navigated using injected ObserverLocator
.
`import {ObserverLocator} from 'aurelia-framework';`
...
this.routerCurrentInstructionSub = this.observerLocator
.getObserver(router, 'currentInstruction')
.subscribe((newValue, oldValue) => { ... });
Note that subscription should be released when not needed to avoid memory leaks this.routerCurrentInstructionSub.dispose();
The main benefit of this solution - is that you get full-featured routes, so you can render tree subitems as active while navigating.
Also it doesn't restrict using sub routers for sub items.
来源:https://stackoverflow.com/questions/41577897/aurelia-easy-way-to-create-nested-multi-level-navigation-menu