【问题标题】:Aurelia: How navigate between child routesAurelia:如何在子路线之间导航
【发布时间】:2026-02-07 11:40:01
【问题描述】:

我正在尝试从一个子路径导航到另一个子路径,但我不断收到Route not found。我的主要问题:如何在子视图之间导航?

下面是代码,下面我还有其他问题。

应用模式-查看 应用类:

export class App {
  configureRouter(config, router) {
    config.title = 'My Site';

    config.map([
      { route: ['','job-view'], name: 'jobView', moduleId: './job-view', nav: true, title:'Jobs'},
      { route: ['services'], name: 'services', moduleId: './services', nav: true, title:'Services'}
    ]);

    this.router = router;
    this.router.refreshNavigation();
  }
}

Q.2:如果router 始终可以从aurelia-router 访问,为什么我们需要在此处保存它?

应用页面:

<template>
  <require from='./nav-bar'></require>
  <nav-bar router.bind="router"></nav-bar>
  <div class="container">
      <router-view></router-view>
  </div>
</template>

好的,现在我们已经定义了根页面视图和导航,让我们定义job-view MV。

JobView 类:

export class JobView {
  configureRouter(config, router) {
    config.map([
      { route: ['','jobs'], name: 'jobs', moduleId: './jobs', nav: false, title:'Jobs', settings:{icon:'glyphicon glyphicon-align-justify'} },
      { route: ['job/:id'], name: 'job', moduleId: './job', nav: false, title:'Job Details'}
    ]);

    this.router = router; //WHY SAVE THIS?
    this.router.refreshNavigation();
  }
}

JobView 页面:

<template>

    <router-view></router-view>

</template>

现在,这里是子视图。我的假设是发生的路由应该与job-view 相关。理想情况下,这就是我想要的。

Jobs Class (为简洁起见删除了一堆代码):

import {Router} from 'aurelia-router';

    @inject(Router)
    export class Jobs {

    constructor(router) {
      this.router = router;
    }

    toJob(id) {
      // this.router.navigateToRoute("job", {id:id}); // ERROR - ROUTE NOT FOUND
      this.router.navigate("#/job-view/job/".concat(id)); // THIS WORKS
    }
}

Q.3:我已经看到router.navigateToRouterouter.navigate 都被引用了,但没有说明何时使用它们或有什么区别,而且文档也没有解释.应该使用哪个? Docs

职位页面: jobs.html 的详细信息无关紧要,因此不在此处列出。

最后,job 视图:

工作类别: job.js 无关,因此不列出代码。最多我可以导航回jobs,但这在页面下方处理。

职位页面:

<!-- a bunch of html //-->
<!-- HOW TO USE ROUTER IN HTML, NOT BELOW URL HREF? //-->
<a href="#/jobs">Print Jobs</a>
<!-- a bunch of html //-->

Q.4:同样,我想路由到相对位置,即使在 HTML 页面中也是如此。上面的不行,那我应该用什么?

在类似的问题中有一个proposed answer,但是将job-view 注入job 并使用job-view 保存的路由器也不起作用。

顺便说一句,如果我手动导航到http://localhost:3000/#/job-view/job/3,页面加载正常,所以很清楚路由器的某些内容。

模组注意事项: 在How to access child router in Aurelia? 上提出了类似的问题,但没有得到有效的解决方案。

【问题讨论】:

    标签: aurelia


    【解决方案1】:

    下面我会尽量一一回答你的问题。

    我将从第二季度开始

    Q.2:如果路由器总是可以从 aurelia-路由器?

    因此,在您的 App Mode-View App Class 中,您在视图中引用了路由器属性:&lt;nav-bar router.bind="router"&gt;&lt;/nav-bar&gt;,这就是您需要声明该属性以使用它的原因。在第二个视图中你不是所以你不需要它:-)

    router 属性也会在您需要对 main.ts / main.js 中的路由器执行某些操作时添加 - 您的应用程序的起点。这是因为第一次配置了路由器,在构造函数中注入将不起作用,所以你需要保存这个属性才能在configureRouter(..)方法中获取它(注意:这是beta 1之前的情况,我没有'不知道现在是否还在)。

    在您的代码中,您需要调用this.router.refreshNavigation();,这将确保您的路由器使用有关路由当前位置的新信息进行更新。

    Q.3:我看到 router.navigateToRoute 和 router.navigate 都被引用了,但没有说明何时使用它们或有什么区别,文档也没有解释。应该使用哪个?文档

    router.navigate(fragment: string, options?: any) 方法使用 URL 片段而不是路由名称来导航,例如router.navigate('#/app/child', {...&lt;options - not params od the URL&gt;...})。此方法必须用于在路由器之间进行绝对导航,以及访问父 URL 等。

    如果您只是在当前路由器中导航,您将始终使用router.navigateToRoute(route: string, params?: any, options?: any)。该方法使用的是路由名称,而不是 URL,我们只是在自定义路由映射中放了一个路由名称(自定义是指当前子路由映射,或当前主路由与我们在页面上的 URL 位置有关)。如您所见,您可以在此处以更方便的方式传递 URL 参数。您可以使用 params 对象而不是将 URL 与 params 连接。

    Q.4:同样,我想路由到相对的,即使是在 HTML 页面中。以上都行不通,那我该怎么用呢?

    在 Aurelia 中,我们不直接使用 a 标签的 href 属性进行导航。正如 Brandon 已经回答的那样,您必须使用 route-href 属性,这可能没有记录在案,只是出现在论坛和门户网站上。这相当于router.navigateToRoute(route: string, params?: any, options?: any),因此您不能使用它在路由器之间导航,在这种情况下您可以使用自定义属性或仅使用click.triger="navTo('#/app/child')",其中navTo() 方法在您的视图模型中实现,如下所示:

    public navTo(routeName: string) {
        // Assuming you are injecting router somewhere in the constructor
        this.router.navigateToRoute(routeName);
    }
    

    最后是你的主题问题:

    Q.1:如何在子路由之间导航

    现在您可能知道答案了,只需使用:router.navigate(fragment: string, options?: any) 和绝对 URL。

    下面的示例自定义属性来解决这个问题:

    import {inject} from "aurelia-dependency-injection";
    import {Router} from "aurelia-router";
    import {customAttribute} from "aurelia-framework";
    
    @customAttribute('nav-href')
    @inject(Element, Router)
    export class NavHref {
        private value: string = '';
    
        constructor(private element: Element, private router: Router) {
            let $this = this;
            element.addEventListener('click', () => {
                if ($this.value === 'back') {
                    $this.router.navigateBack();
                } else {
                    // expression
                    $this.router.navigate($this.value);
                }
            });
        }
    
        public valueChanged(newValue: string, oldValue: string) {
            this.value = newValue;
        }
    }
    

    首先你需要在你的 HTML 中导入它,我将我的文件命名为 nav.href.ts:

    <require from="common/nav.href"></require>
    

    然后在你的 HTML 代码中使用它:

    <a nav-href="#/home/any-location">My link to any location</a>
    

    希望这会对你有所帮助,干杯 :-)

    【讨论】:

      【解决方案2】:

      我在 Aurelia 应用程序中配置子路由器的方式是这样的:

      app.js
      
      export class App {
          configureRouter(config, router) {
              config.map([
                  { route: ['','home'], name: 'home', moduleId: 'home', nav: true },
                  { route: 'work', name: 'work', moduleId: 'work/work-section', nav: true },
              ]);
              this.router = router;
          }
      }
      
      
      work/work-section.js
      
      export class WorkSection {
      
          configureRouter(config, router) {
              config.map([
                  { route: '', moduleId: './work-list', nav: false },
                  { route: ':slug', name: 'workDetail', moduleId: './work-detail', nav: false }
              ]);
              this.router = router;
          };
      
      }
      

      对应的“work-section.html”只是一个Router View:

      <template>
          <router-view></router-view>
      </template>
      

      在这个用例中,我的主 app.js 定义了一个子路由器“work”,它位于 src 下的子目录中。

      当路由/work被激活时,子路由器“work-section”接管,激活“work-list”路由,因为路径段在那里结束:/work

      “work-list.js”从 REST API 检索项目,然后将数据传递给视图。 从那里,我可以使用路由绑定来获取“work-list.html”视图中的“工作详细信息”:

      <div repeat.for="sample of item.samples">
          <a route-href="route: workDetail; params.bind: { slug: sample.slug }">
              ${sample.title}
          </a>
      </div>
      

      希望对您有所帮助。如果您询问如何进行重定向或如何从视图导航到子路线,我不能 100% 确定,所以如果我错了,请纠正我,我会尽力更新我的答案给你。

      【讨论】:

      • route-href 不是我以前见过的东西。有趣的。有文档吗?有机会我会试试的。我遇到的问题是我的电话this.router.navigateToRoute("job", {id:id});。我会更新问题以反映这一点。
      • 很抱歉给您回复的巨大延迟。 route-href 位于“生成路由 URL”aurelia.io/docs.html#/aurelia/framework/1.0.0-beta.1.1.2/doc/… 下的备忘单中
      • this.router.navigateToRoute('workDetail', {slug:'slug'});(或者应该是this.router.navigate('workDetail', {slug:'slug'});)是否在workDetail.js 中工作(假设configureRouterworkDetail 类上捕获router)?
      • 很抱歉延迟回复您。稍后我会在这里为您试一试。
      • 你能测试一下吗?