在Aurelia子路由器上使用命名路由

时间:2017-02-09 13:47:33

标签: aurelia aurelia-router

我有3级嵌套路由器,定义如下:

app.js

configureRouter(config, router) {
  this.router = router;
  config.title = 'EagleWeb';
  var step = new AuthorizeStep(this.core);
  config.addAuthorizeStep(step);
  config.map([
    { route: '', redirect: 'home' },
    { route: 'home',              name: 'home',               moduleId: 'home/home' },
    { route: 'users',             name: 'users',              moduleId: 'users/user-home' },
    { route: 'accounting',        name: 'accounting',         moduleId: 'accounting/accounting' }
  ]);
}

占/ accounting.js

configureRouter(config, router) {
  config.map([
    { route: '', redirect: 'home' },
    { route: 'home',      name: 'accounting-home',              moduleId: 'accounting/accounting-home' },
    { route: 'accounts',  name: 'accounting-accounts',          moduleId: 'accounting/accounts/accounts' },
    { route: 'entries',   name: 'accounting-entries',           moduleId: 'accounting/entries/entries' }
  ]);
  this.router = router;
}

会计/帐户/ accounts.js

configureRouter(config, router) {
  config.map([
    { route: '',          redirect: 'list' },
    { route: 'list',      name: 'accounting-account-list',              moduleId: 'accounting/accounts/account-list' },
    { route: 'view/:id',  name: 'accounting-account-view',              moduleId: 'accounting/accounts/account-view' }
  ]);
  this.router = router;
}

我想导航到第三级,它可以使用普通的链接标记或直接在URL中输入(例如<a href="#/accounting/accounts/view/2">),但以下命名路由的方法都不起作用:

  1. (来自app.html,级别1尝试访问级别3)<a route-href="route: accounting-account-list">Account List</a>
  2. (来自app.html,级别1尝试访问级别3)<a route-href="route: accounting-account-view; params.bind: {id: 2}">Account #2</a>
  3. (来自accounting-home.js,级别2尝试访问级别3)this.router.navigateToRoute('accounting-account-view', {id: 2});
  4. (来自accounting-home.js,级别2尝试访问级别3)this.router.navigateToRoute('accounting/accounting-accounts/accounting-account-view', {id: 2});
  5. 对于#1-2,我在应用程序加载时收到Error: A route with name 'accounting-account-list' could not be found. Check that name: 'accounting-account-list' was specified in the route's config.之类的控制台日志错误,并且链接已经死亡。

    对于#3-4,我收到了Uncaught Error: A route with name 'accounting-account-view' could not be found.等控制台日志错误。当页面加载时以及每次导航时,我在控制台日志中也会收到很多警告,例如Warning: a promise was rejected with a non-error: [object Object] at _buildNavigationPlan

    我做错了什么?我是否需要做一些特殊的事情来访问不同路由器级别的路由?

    附带问题:我是否需要在每个视图模型中import {Router} from 'aurelia-router';,有些或没有?我需要注射吗?

1 个答案:

答案 0 :(得分:5)

我在一个星期前在客户端项目上遇到了同样的情况。实际上,这里唯一的选择是预先创建所有路线然后导入它们。如果您有单独的部分(我将进一步解释),您可以通过setRoot切换根来缓解此问题。

我的情景非常相似。我有一个已注销的视图,其中包含一些路径; loginregisterforgot-passwordpage/:page_slug(这是用于呈现静态网页)。然后我有一个登录的仪表板视图,其中包含一系列路径。

免责声明:以下代码示例尚未经过测试,只能用作指南。我也使用TypeScript而不是普通的旧Javascript。将以下内容转换为Javascript(如果需要)应该相当简单。以下是我使用的内容,可能有更好的方法。

我登录的仪表板视图中有很多部分需要放入分层下拉菜单中,类似于以下内容:

Users
    Add
    List
    Manage
Experiments
    Add
    List
    Manage
Activities
    Add
    List
    Manage
Ingredients
    Add
    List
    Manage
Account
    Profile
    Notifications
    Billing
    Settings

这是每页显示的菜单。子路由器的问题是路由未提前知道,它们是动态的(即使您定义它们)。只有当您实例化视图模型(即导航到它)时,Aurelia才会知道路线。

我最终选择的解决方案并不理想,但它有所帮助。

我将所有非auth / public面向的路线分成一个名为src/public-routes.ts的文件

export default [
    {route: 'login', name: 'login', moduleId: './public/login'},
    {route: 'register', name: 'register', moduleId: './public/register'},
    {route: 'forgot-password', name: 'forgot', moduleId: './public/forgot-password'},
    {route: 'pages/:page_slug', name: 'page', moduleId: './public/page'},
];

然后我专门为这些名为src/public-app.ts的公共路由创建一个根文件,附带src/public-app.html(包含路由器视图):

import PublicRoutes from './public-routes';

export class PublicApp {
    configureRouter(config: RouterConfiguration, router: Router) {
        config.map(PublicRoutes);
    }
}

然后我为我的私人仪表板路线重复相同的操作。分别用Publicpublic替换Privateprivate的实例。使用平面路线方法的一个很好的建议是,如果您有很多路线,请不要将所有路线都集中到一个文件中。

我最终为私人路线做的是为每个部分创建路径文件。所以我的用户路由有自己的文件user.routes.ts,我的帐户路由有自己的文件account.routes.ts,依此类推。然后我将它们导入我的主文件(在这种情况下为private-routes.ts)。

然后在我的src/main.ts文件内部根据用户是否登录来切换根目录:

export async function configure(aurelia: Aurelia) {
  aurelia.use
    .standardConfiguration()
    .feature('resources');

  let auth = aurelia.container.get(Auth);
  let root = auth.isLoggedIn ? './private-app' : './public-app';

  await aurelia.start();
  aurelia.setRoot(root);
}