如何定义和渲染子菜单项,使用Aurelia's路由器
How to define and render submenu-items, using Aurelia's Router
在Aurelia应用程序中,我定义了一个简单的路由,如下所示:
configureRouter(config: RouterConfiguration, router: Router) {
config.title = 'Marino';
config.map([
{ route: ['', 'home'], name: 'home', moduleId: './pages/home/home', nav: true, title: 'Home' },
{ route: 'colors', name: 'colors', moduleId: './pages/colors/overview', nav: true, title: 'Colors' }
]);
this.router = router;
}
正如所有例子提到的那样,通过实现repeat.for和href.bind,这是完美的:
<ul class="main-navigation">
<li repeat.for="row of router.navigation" class="${row.isActive ? 'active' : ''}">
<a class="btn btn-primary" href.bind="row.href">${row.title}</a>
</li>
</ul>
我的场景中的挑战是,我想也将带有子菜单项的路由动态渲染到此菜单。类似这样的东西:
<ul class="main-navigation">
<!-- the regular 'regular' menu and works just fine -->
<li repeat.for="row of router.navigation" class="${row.isActive ? 'active' : ''}">
<a class="btn btn-primary" href.bind="row.href">${row.title}</a>
</li>
<!--
below is the pickle; a different kind of element (non-clickable),
but with child elements
-->
<li class="main-navigation-dropdown">
<a class="btn btn-primary">Menu with Submenu-items</a>
<div class="horizontal-dropdown-menu">
<a class="btn btn-primary sideline">Submenu 1</a>
<a class="btn btn-primary sideline">Submenu 2</a>
<a class="btn btn-primary sideline">Submenu 3</a>
</div>
</li>
</ul>
让我困惑的是两件事:
- 如何正确定义路由配置中的子菜单项
- 如何有条件地将每条路线渲染为常规(可单击)路线,或者渲染为具有子菜单的不可单击项目
我查看了RouteConfig文档,但似乎找不到任何关于"嵌套"子例程的信息。Aurelia Getting Started确实提供了关于子路线的信息,但在我看来,所有的示例都与在另一个组件上显示"其他"或第二个菜单有关。
我确信这很琐碎,但我似乎无法解决它。
我用ValueConverter解决了这个问题。这只适用于两个级别,但只要稍作更改,它可以支持更多级别。
路线-settings.parentMenu定义它将出现在哪个菜单下。
export class App {
configureRouter(config, router) {
config.title = 'Aurelia';
config.map([
{ route: ['', 'welcome'], name: 'welcome', moduleId: 'welcome', nav: true, title: 'Welcome', settings: { icon : 'fa-th-large'} },
{ route: '#', name: 'admin', moduleId: 'admin', nav: true, title: 'Admin', settings: { icon : 'fa-user' } },
{ route: 'admin/templates', name: 'admin-templates', moduleId: 'users/users', nav: true, title: 'Templates', settings: { parentMenu: 'Admin'} }
]);
this.router = router;
}
}
subMenu.js-将子菜单分组到父下
export class SubMenuValueConverter {
toView(routerMenuItems) {
var menuItems = [];
routerMenuItems.forEach(function (menutItem) {
if (menutItem.settings.parentMenu) {
// Submenu children
var parent = menuItems.find(x => x.title == menutItem.settings.parentMenu);
// If it doesn't exist, then something went wrong, so not checking
parent.children.push(menutItem);
} else {
// Just insert. It should not be there multiple times or it's a bad route
menuItems[menutItem] = menuItems[menutItem] || [];
// Create empty children
menutItem.children = [];
menuItems.push(menutItem);
}
});
return menuItems;
}
}
nav bar.html-通过管道将router.navigation导入subMenu值转换器,然后在绑定子菜单时检查子菜单。
<template bindable="router">
<require from="./subMenu"></require>
<nav role="navigation">
<li repeat.for="row of router.navigation | subMenu" class="${row.isActive ? 'active' : ''}">
<a href="${row.children.length == 0 ? row.href : 'javascript:void(0);'}">
<i class="fa ${row.settings.icon}"></i>
<span class="nav-label">${row.title}</span>
</a>
<ul if.bind="row.children.length > 0" class="nav nav-second-level">
<li repeat.for="sub of row.children" class="${sub.isActive ? 'active' : ''}">
<a href.bind="sub.href">
<i class="fa ${subrow.settings.icon}"></i>
<span class="nav-label">${sub.title}</span>
</a>
</li>
</ul>
</li>
</nav>
</template>
我不知道这是否是正确的方法,但这是我发现的最不"时髦"的方法。如果你使用的是子路由,那么除非你将子路由器注入到你的app.js中(或者在你定义路由的任何地方),并调用configureRouter并传入主路由器的配置,否则这是行不通的。我发现这在主路由器上注册了所有的路由,尽管对我来说这似乎真的很糟糕。
问题是子路由往往使用子路由器。
这在Aurelia中实现了一些非常强大的场景,但带来了一个挑战,即在导航到子路线之前,您的路线配置可能不会出现。
我以前已经处理过这种情况,通过证明一个路由服务,它将路由树作为一个单独的对象,并使用一些辅助方法将其中的一部分转换为Aurelia可以使用的路由配置对象。
然后将其注入到子模块中,它们对其进行查询以配置路由器
导航菜单组件可以查看该树,在加载任何子模块之前构建菜单结构。
Mike Graham也做了类似的事情,但他只是预先设置所有的路线配置(使用路线配置上的"级别"变量来确定菜单继承权):
Aurelia:子路由器路由显示在";主";app.html中的导航栏和子视图<路由器视图>要素
这种方法的缺点是,为了配置路由器,您需要提前了解子模块。(子路由器的部分功能是,它们可以在运行时注册,并且可以在托管应用程序中的任何其他地方"插入",而无需任何配置-这抵消了这一优势)
上述方法的缺点是,你不能很容易地使用路由器生成路由href(因为它使用父路由来计算相对href),你最终不得不自己构建导航模型。
- 如何在Javascript/ES6中的Aurelia浏览器应用程序中使用AWS S3
- 如何定义和渲染子菜单项,使用Aurelia's路由器
- 如何在Aurelia中使用socket.io
- 使用EventAggregator更新Aurelia中的列表
- Aurelia类的问题.使用checked.bind绑定
- Aurelia的“repeat.for”可以与“view-model.ref”一起使用吗?
- 使用 Aurelia动态创建一个 dom 对象
- 在 aurelia 中使用 repeat.for 绑定自定义元素的正确方法是什么
- 使用 Materialize css 在 Aurelia 中选择
- 使用Aurelia的架构形式
- 使用 Aurelia在视图中动态生成自定义组件
- 注入多个在Aurelia中使用fetch HttpClient的类
- 在Aurelia应用程序中使用Google的reCAPTCHA
- 在Aurelia中使用带有FileList的@computedFrom
- 有条件地显示使用Aurelia的元素
- 如何使用 Aurelia.io 增强服务器端生成的页面
- 如何使用Aurelia将换行符渲染为
标签 - 如何使用路由器和内置/自定义属性在aurelia中创建下拉菜单
- Aurelia使用ES5计算属性
- Aurelia使用值转换器限制打印值