Aurelia路由器 - 带下拉菜单的导航栏

时间:2016-07-17 20:58:05

标签: aurelia aurelia-router

假设我们有bootstrap 3导航栏,模板的一部分可能如下所示:

<ul class="nav navbar-nav">
    <li repeat.for="row of router.navigation" class="${row.isActive ? 'active' : ''}">
        <a data-toggle="collapse" data-target="#skeleton-navigation-navbar-collapse.in" href.bind="row.href">${row.title}</a>
    </li>
</ul>

这也是Aurelia docs的例子。

现在让我们说,我想添加一个带下拉列表的项目:

<ul class="nav navbar-nav">
    <li repeat.for="row of router.navigation" class="${row.isActive ? 'active' : ''}">
        <a data-toggle="collapse" data-target="#skeleton-navigation-navbar-collapse.in" href.bind="row.href">${row.title}</a>
    </li>
    <li class="dropdown">
        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button">Dropdown <span class="caret"></span></a>
        <ul class="dropdown-menu">
            <li><a href="#">Some page</a></li>
            <li><a href="#">Some other page</a></li>
        </ul>
    </li>
</ul>

如何为此下拉列表配置路由? 我需要第二个路由器吗?儿童路由器?

2 个答案:

答案 0 :(得分:5)

您不必使用nav属性

根据我的经验,nav属性充其量只是一个很好的概念证明。实际上,大多数应用程序都有更复杂的菜单,更适合于它们背后更复杂的数据结构。

策略1:硬编码菜单

对于不太复杂的情况,特别是那些不太可能接收更多复杂路径的定义良好的应用程序,只需将它们硬编码到视图中即可。

<ul class="nav navbar-nav">
  <li>
    <a data-toggle="collapse" data-target="#skeleton-navigation-navbar-collapse.in" href="#/first">
      First
    </a>
  </li>
  <li class="dropdown">
    <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button">Menu <span class="caret"></span></a>
    <ul class="dropdown-menu">
      <li><a href="#/sub-one">Sub Item 1</a></li>
      <li><a href="#/sub-two">Sub Item 2</a></li>
    </ul>
  </li>
</ul>

这种策略失去了所有有趣,华丽的Aurelia数据绑定功能。但它可能会节省你的时间。它简单明了,不会留下任何漏洞。它只是HTML。这样做的主要缺点是需要对isActive属性进行一些额外的编码,但编写此代码比尝试编写动态嵌套菜单要容易得多。

策略2:创建自定义菜单模型

对于更复杂,动态的情况,特别是当您不知道在运行时会发生什么时,我建议您创建自己的类或界面来描述您的菜单。

models / menuItem.ts

export interface MenuItem {
    title: string;
    route?: string | string[];
    children?: MenuItem[];
}

<强> app.ts

const MENU = [{
    title: 'First',
    route: '#/first'
},{
    title: 'Menu',
    children: [{
        title: 'Sub Item 1',
        route: 'sub-one',
    },{
        title: 'Sub Item 2',
        route: '#/sub-two'
    }]
}];

这有点复杂,但为您提供了大量的可自定义性和灵活性,默认路由器navModel没有。

答案 1 :(得分:3)

一种选择是在路由器配置上创建自定义设置属性,然后根据需要过滤掉导航项。注意:这感觉有点hackish,可能还有其他选择,但这是我能想到的。

configRouter方法

// the first 2 items will show up in the navigation.
// the last 2 items will only show up in the drop down navigation.
config.map([
        {
            route: ["", "home"],
            name: "home",
            moduleId: "home/index",
            title: "Home",
            nav: true
        },
        {
            route: "about-me",
            moduleId: "about/about",
            title: "About",
            nav: true
        },
        {
            route: "some-page",
            moduleId: "some/page",
            title: "Some Page",
            nav: true,
            settings: {dropdown: true}
        },
        {
            route: "some-other-page",
            moduleId: "some/otherPage",
            title: "Some other Page",
            nav: true,
            settings: {dropdown: true}
        }
    ]);

导航栏

<!-- 
    Note the use of if.bind="!nav.settings.dropdown" in the first repeat.for.
    Note the use of if.bind="nav.settings.dropdown" in the drop down repeat.for.
-->
<ul class="nav navbar-nav">
    <li repeat.for="row of router.navigation" class="${row.isActive ? 'active' : ''}">
        <a if.bind="!nav.settings.dropdown" 
            data-toggle="collapse" 
            data-target="#skeleton-navigation-navbar-collapse.in" 
            href.bind="row.href">${row.title}</a>
    </li>
    <li class="dropdown">
        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button">Dropdown <span class="caret"></span></a>
        <ul class="dropdown-menu">
            <li repeat.for="nav of router.navigation" class.bind="nav.isActive ? 'active' :''">
                <a if.bind="nav.settings.dropdown"
                    href.bind="nav.href">${nav.title}</a>
             </li>
        </ul>
    </li>
</ul>