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

LSt*_*rky 7 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' }
  ]);
}
Run Code Online (Sandbox Code Playgroud)

会计/ 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;
}
Run Code Online (Sandbox Code Playgroud)

会计/会计/ 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;
}
Run Code Online (Sandbox Code Playgroud)

我想导航到第三级,它可以使用普通的链接标记或直接在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});

对于#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';在每个视图模型中,某些模型,或者没有模型?我需要注射吗?

Dwa*_*ton 5

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

我的情况非常相似.我有一个已注销的视图,其中包含一些路径; login,register,forgot-password和,page/: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
Run Code Online (Sandbox Code Playgroud)

这是每页显示的菜单.子路由器的问题是路由未提前知道,它们是动态的(即使您定义它们).只有当您实例化视图模型(即导航到它)时,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'},
];
Run Code Online (Sandbox Code Playgroud)

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

import PublicRoutes from './public-routes';

export class PublicApp {
    configureRouter(config: RouterConfiguration, router: Router) {
        config.map(PublicRoutes);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

我最终为私人路线做的是为每个部分创建一个路径文件.所以我的用户路由有自己的文件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);
}
Run Code Online (Sandbox Code Playgroud)