【问题标题】:Aurelia Router/Child Router - 'Error: Route not found'Aurelia 路由器/子路由器 - '错误:找不到路由'
【发布时间】:2017-09-25 04:52:03
【问题描述】:

我正在尝试使用以下配置设置应用:

~授权控制的基础页面有两个

  • 登录页面 - 如果没有会话 ID
  • 仪表板页面 - 如果已登录

~ 在仪表板页面上,我想将其用作其他视图的一种容器。仪表板基本上只是一个带有导航栏和router-view 的模板。我希望路由器视图能够在 2 个页面/视图之间切换,同时将仪表板/导航保持在适当的位置作为布局。两个页面是要切换的

  • 更新提要
  • 测试页

这是我目前设置的文件

app.ts

import {NavigationInstruction, Next, Redirect, Router, RouterConfiguration} from 'aurelia-router';

/**
 * Main application router, controls views by authorization
 */
export class App {

  public router: any;

  public configureRouter(config: RouterConfiguration, router: Router): void {
    config.title = 'Dashboard';
    config.addPipelineStep('authorize', AuthorizeStep);

    // These are the two main routes a login page and a dashboard. 
    // Which page is visible is controlled by the authorization step
    config.map([
      {route: ['', 'pmdash'], name: 'pmdash', moduleId: './pages/pmdash/pmdash', nav: true,  auth: true},
      {route: 'login',        name: 'login',  moduleId: './pages/login/login',   nav: false, auth: false, title: 'Login'}
    ]);
    this.router = router;
    console.log(this.router);
  }
}

export class AuthorizeStep {

  // Method may be used elsewhere to verify user is logged in
  public static isLoggedIn(): boolean {
    let sessionID = sessionStorage.getItem('sessionID');
    return (typeof sessionID !== 'undefined' && sessionID !== null);
  }

  public run(navigationInstruction: NavigationInstruction, next: Next): Promise<any> {

    if (navigationInstruction.getAllInstructions().some(i => i.config.auth)) {
      let isLoggedIn = AuthorizeStep.isLoggedIn();

      if (!isLoggedIn) {
        return next.cancel(new Redirect('login'));
      }
    }
    return next();
  }
}

app.ts 控制您是登陆登录页面还是登陆基于会话 ID 的仪表板。这可行,但是一旦登陆仪表板页面,它就会开始变得混乱......这是仪表板和相应的导航栏文件

pmdash.html

<!-- Base template for PM Dashboard views -->

<template>

  <require from="../../components/navbar/navbar"></require>
  <nav-bar></nav-bar>
  <router-view></router-view>

</template>

pmdash.ts

import {Router, RouterConfiguration} from 'aurelia-router';

/**
 * Child router for Dashboard pages/views
 */
export class DashBoard {

  public router: Router;

  // On immediate navigation to the dashboard this loads `update-feed`, which works
  // However it only works because it is assigned the base route ''.
  // If I try to navigate to `update-feed` or `test-page` by url I get `Error: Route not found:` in console 
  public configureRouter(config: RouterConfiguration, router: Router) {
    config.map([
      {route: ['', 'update-feed'], name: 'update-feed', moduleId: './pages/update-feed/update-feed', nav: true, title: 'Feed'},
      {route: ['test-page'],       name: 'test-page',   moduleId: './pages/test-page/test-page',     nav: true, title: 'Test'}
    ]);
    this.router = router;

    // These console logs show the router is the child of `AppRouter` and has all the routes assigned to it, like it should.
    console.log(this.router);
    console.log(this.router.routes);
  }

}

navbar.html

<template>

  <nav class="navbar navbar-default navbar-fixed-top" role="navigation">

    <!-- Here is an effort to bind the router to the navigation -->
    <div class="navbar-header" router.bind="router">

      <!-- Here again clicking on the link gives `Route not found: /update-feed`-->
      <a class="navbar-brand" route-href="route: update-feed">
        <i class="fa fa-user"></i>
        <span>PM Dashboard</span>
      </a>

      <!-- This works. It calls the logout function which then redirects to the login page on the main router-->
      <button type="button" class="btn btn-default navbar-btn pull-right" click.delegate="logOut()">Log Out</button>
    </div>
  </nav>

</template>

navbar.ts 现在navbar.ts 只包含logOut() 函数,所以为了简洁我跳过代码。

现在这是我希望pmdash.ts 子路由器控制的两个页面。基本上我设置它的方式我希望当登陆pmdash页面/路由时pmdash视图/视图模型应该处理这些页面/视图,同时留在pmdash作为带有导航栏的模板在顶部,然后根据链接(或默认)切换出在导航栏下方显示的视图。

update-feed.html

<template>

  <h1>You currently have no projects needing updated.</h1>

  <!-- Clicking this link gives `Error: Route not found: /test-page` in console-->
  <a route-href="route: test-page">click for test page</a>

</template>

test-page.html

<template>
  TESTING
  <!-- Clicking this link gives `Error: Route not found: /update-feed` -->
  <a route-href="route: update-feed">click for route page</a>
</template>

update-feed.html 和 test-page.html 都关联了 .ts 文件,但现在它们是空白的。

我只是不明白我做错了什么。我是否误解了路由器/子路由器如何从根本上处理页面?有什么方法可以使配置像我目前拥有的那样工作,还是我需要放弃这种方法并尝试完全不同的方法?

同样,主要问题是pmdash child-router 不会使用update-feed 和test-page 路由切换视图。但是,如果我将其中一个路由分配为route: '',那么它会正常加载,但我仍然无法链接到另一个路由/视图。

【问题讨论】:

  • 如果您已经回答了自己的问题,请添加并接受并回答 - 而不是编辑您的原始帖子。
  • 我没有打开它,因为这个“答案”更像是一种解决方法/黑客。我会编辑

标签: typescript aurelia


【解决方案1】:

好的,我已经“修复”了这个问题,方法如下:

起初我并不认为 [this SO question][1] 与我的情况有关,但确实如此。

基本上,问题在于在将路由传递给子路由器时处理绝对路由和基本路由(即route: '')没有得到正确处理。

解决方法是让父路由器像这样重定向(以我自己的上面的app.ts 为例):

  public configureRouter(config: RouterConfiguration, router: Router): void {
    config.title = 'Dashboard';
    config.addPipelineStep('authorize', AuthorizeStep);
    config.map([
      {route: '',      redirect: 'dashboard'},
      {route: 'dashboard', name: 'pmdash', moduleId: './pages/pmdash/pmdash', nav: true,  auth: true},
      {route: 'login',     name: 'login',  moduleId: './pages/login/login',   nav: false, auth: false, title: 'Login'}
    ]);
    this.router = router;
    console.log(this.router);
  }

这显然是a workaround to a known issue with how the router handles an array of routes with a child router。但是,尽管解决方法确实有效,但控制台现在会在应用程序根路由被击中时发出此警告 Warning: a promise was rejected with a non-error: [object Object] at _buildNavigationPlan....。此警告似乎尚未体现为任何实际问题...

真是头疼

【讨论】:

  • 我可以回答“警告你的承诺被拒绝的事情.....”:-)
  • @shawty:无论如何!你有解决办法吗?
  • 基本上,当你拒绝而不使用“throw”时,你会明白,过去几天我在我一直在做的项目上遇到了一堆问题。这样做的不是 Aurelia,实际上是 AU 使用的承诺库 Bluebird。在你的捕获中,如果你“throw new Error('foo')”你会发现你没有收到警告,但是如果你“throw Error({prop: 1, prop2:'two'})”你会.然而有一个秘密:-) 如果你“抛出 Error({name: "myCustomErrorName", message: "My custom error message", ... then your custom data here ... })" ,蓝鸟认为这是一个sigs 匹配时出现合法的新错误。
  • 有趣。是的,我认为这是一只蓝鸟,但有点放弃了进一步的检查。只是因为把这个放在一起而被烧毁了哈哈。我会试一试并回帖。谢谢!
  • 这允许您将错误返回,传递自定义数据,但不会收到警告。如果它来自你的调用 EG: 在 au-fetch 中,那么你需要将它包装在你自己的 Promise 中,然后重新将它扔到 catch 中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多