【问题标题】:Aurelia router - navbar with dropdownsAurelia 路由器 - 带有下拉菜单的导航栏
【发布时间】:2016-07-19 03:22:33
【问题描述】:

假设我们有 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>

如何为此下拉菜单配置路由? 我需要第二个路由器吗?子路由器?

【问题讨论】:

    标签: aurelia


    【解决方案1】:

    您不必使用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 所没有的大量可定制性和灵活性。

    【讨论】:

      【解决方案2】:

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

      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>
      

      【讨论】:

      • IMO 这是最正确的答案。它使用路由功能来添加通常用于身份验证的自定义属性(auth: true in setting property)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-07
      • 1970-01-01
      相关资源
      最近更新 更多