我需要创建一个多级导航菜单。菜单的内容因用户而异。我计划通过一个将数据作为JSON返回的服务来提取导航项的集合,这些导航项可以包含一组子项。我看到的每个导航/路由示例都使用静态路由或单层菜单。我读过一些关于儿童路由的文章,但这似乎不是我需要的。我唯一能想到的就是创建一个自定义导航元素,该元素的模型将使用导航项集合中的数据在纯数组中注册路线。然后我会使用这个集合来呈现HTML,而不是使用路由器,因为它包含层次信息。有更简单的方法吗。这是我使用过的第一个JS框架,所以我正在努力跟上进度。
实际上,这相当容易。您只需将特性添加到路由的settings
对象中。你可以随心所欲地命名它。它将有一个子菜单的菜单项集合。只需使用它来构建子菜单。
以下是一个示例: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);
}
}
您传递的参数可以是任何您喜欢的参数。例如,它们可以是关于应该在您要去的路由上的子路由器上激活的路由的信息。您可以在页面的激活方法中调用router.navigate...
(下面示例中的one.js
),以导航到子路由器上的正确路由。你真的可以做任何你想做的事,因为你可以把你想要的任何旧东西放在设置对象上。
我用以下方式解决了类似的问题:
- 我有从服务器检索到的简单导航树
- 然后我遍历树,将所有导航项转换为aurelia路由,实际上将树展平为数组,因此此时每条路由都将具有设置属性,如:
{id: 2, parentId: 1, level: 1}
- 然后,我将这个平面数组传递给
config.map()
,并使用router.navigation
中的项在router.ensureConfigured().then(_ => {createNavTree(router.navigation)})
上创建一个新的树对象(记住:我在settings
中保存了id
和parentId
) - 使用
createNavTree(...)
的输出来呈现列表项。(level
仅用于某些样式) - 因此,通常我会创建平面
router.navigation
数组,并使用其项创建自己的树结构来渲染导航
此外,当使用注入的ObserverLocator
导航子项时,我会监听router.currentInstruction
中的更改,以跟踪菜单折叠。
`import {ObserverLocator} from 'aurelia-framework';`
...
this.routerCurrentInstructionSub = this.observerLocator
.getObserver(router, 'currentInstruction')
.subscribe((newValue, oldValue) => { ... });
请注意,在不需要时应发布订阅以避免内存泄漏this.routerCurrentInstructionSub.dispose();
此解决方案的主要好处是,您可以获得功能齐全的路由,因此您可以在导航时将树子项渲染为活动的。
此外,它没有限制使用子项目的子路由器。