Aurelia:创建嵌套/多级导航菜单的简便方法

时间:2017-01-10 20:35:23

标签: javascript aurelia aurelia-framework

我需要创建一个多级导航菜单。菜单的内容因用户而异。我计划通过一个将数据作为JSON返回的服务来提取可以包含子项目数组的导航项集合。我见过的每个导航/路由示例都使用静态路由或单级菜单。我已经阅读了一些关于子路由的内容,但这似乎不是我需要的。我唯一能想到的是创建一个自定义导航元素,该模型将使用导航项集合中的数据在普通数组中注册路径。然后我会使用此集合来呈现HTML而不是使用路由器,因为它包含分层信息。有没有更简单的方法来做到这一点。这是我使用的第一个JS框架,所以我试图加快速度。

2 个答案:

答案 0 :(得分:4)

实际上,这很容易。您只需在路由的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);
  }
}

您传递的参数可以是您喜欢的任何内容。例如,它们可能是关于您将要去往的路线上的子路由器应该激活的路线的信息。您可以在页面的activate方法中调用router.navigate...(在下面的示例中为one.js)以导航到子路由器上的正确路由。你真的可以做任何你想做的事,因为你可以在你的设置对象上放置任何旧的东西。

答案 1 :(得分:1)

我通过以下方式解决了类似的问题:

  1. 我从服务器检索了简单的导航树
  2. 然后我走在树上并将所有导航项转换为aurelia路线,实际上将树变平为阵列,因此每条路线都会有如下设置属性:{id: 2, parentId: 1, level: 1}
  3. 然后我将此平面数组传递给config.map()并使用router.navigation中的项目创建新的树对象(请记住:我在id中保存了parentIdsettingsrouter.ensureConfigured().then(_ => {createNavTree(router.navigation)})
  4. 使用createNavTree(...)的输出来呈现列表项。 (level仅用于某些样式)
  5. 所以一般来说我创建平面router.navigation数组并使用它的项来创建自己的树结构来渲染导航
  6. 此外,当我使用注入的router.currentInstruction导航子项时,我会在ObserverLocator中收听更改以跟踪菜单折叠。

    `import {ObserverLocator} from 'aurelia-framework';`
    ...
    this.routerCurrentInstructionSub = this.observerLocator
      .getObserver(router, 'currentInstruction')
      .subscribe((newValue, oldValue) => { ... });
    

    请注意,应在不需要时释放订阅以避免内存泄漏this.routerCurrentInstructionSub.dispose();

    此解决方案的主要优点是,您可以获得功能齐全的路线,因此您可以在导航时将树子项目渲染为活动状态。

    此外,它不会限制子路由器使用子项。