Aurelia router - navbar with dropdowns

。_饼干妹妹 提交于 2020-01-06 02:46:03

问题


Let's say we have bootstrap 3 navbar, and part of the template could look like this:

<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>

This is also example from Aurelia docs.

Now let's say, I'd like to add one item with dropdown:

<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>

How can I configure routes for this dropdown? Do I need second router? Child router?


回答1:


You don't have to use the nav property

In my experience, the nav property is at best a nice proof of concept. In practice, most applications have more complicated menus, and are better suited to more complex data structures behind them.

Strategy 1: Hard code the menu

For not-too-complex situations, especially well defined applications that are unlikely to receive more, complicated routes, just hard code them into the view.

<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>

This strategy loses all of the fun, flashy Aurelia-enabled data-binding. But it might save you hours. It is simple and straightforward, and leaves no room for bugs. It's just HTML. The major downside as that this requires a little bit of additional coding for the isActive property, but its significantly easier to write this code than to try to write a dynamic, nested menu.

Strategy 2: Create a custom menu model

For more complex, dynamic situations, especially when you have little idea what to expect at runtime, I recommend creating your own class or interface that describes your menu.

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'
    }]
}];

This is quite a bit more complicated, but affords you a great deal of customizability and flexibility that the default router navModel does not.




回答2:


One option would be to create a custom settings property on the configuration of the router and then filter out the navigation items as needed. Note: This feels a bit hackish and there may be other alternatives, but this is what I could come up with.

configRouter method

// 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}
        }
    ]);

Navigation Bar

<!-- 
    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>


来源:https://stackoverflow.com/questions/38425867/aurelia-router-navbar-with-dropdowns

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!