Angular2 named routes

2020-02-26 03:03发布

问题:

I use Angular2 Webpack Starter in this newest version and in file ./src/app/app.routes.ts I add 'my-new-route' and i want to name it as: "my.route"

export const routes: RouterConfig = [
  { path: '',      component: Home },
  { path: 'home',  component: Home },
  // make sure you match the component type string to the require in asyncRoutes
  { path: 'about', component: 'About' },
  { path: 'my-new-route', component: 'Dashboard', name:"my.route" },
  { path: '**',    component: NoContent },
];

but there is a problem - it not working! TypeScript writes: (name) "... is not assignable to type Route[]". I check file node_modules/@angular/router/config.d.ts (which was pointed in index.d.ts) and indeed - there is no 'name' field in RouterConfig (Route class). So how to do named routes in Angular2 ?

回答1:

I would just use ng2-translate and create the link for each language in your JSON files.



回答2:

There is a way to have named routes in new Angular2 router (which don't support it) (the main idea is from checked answer - @Michael Robison) :

in file app.routes.ts i have:

...
import { Url } from './common/url';

export const routes: RouterConfig = [
  { path: '',       component:  LoginForm },
  { path: Url.to('login'),  component: LoginForm },
  { path: Url.to('home'), component: Home, canActivate: [AllAuthGuard] },
  { path: Url.to('clients'), component: Cliens, canActivate: [AdminAuthGuard] },
  { path: Url.to('projects'), component: Projects, canActivate: [AdminAuthGuard] },
  ...
  { path: '**',     component: LoginForm },
];

And in /app/common/url.ts I have something similar to (i make below code here by hand without checking it):

export class Url {
    map = {
      'login': 'my-super-login',
      'home': 'my-link-home',
      'clients': 'favourite-clients',
      'projects': 'bets-projects',
    }

    public static to(routingName : string) {
        return this.map[routingName];
    }

}

And every where in your project in links you must also use Url.to(...) method (in Controllers make method links(route) which call Url.to, and use it in template...). Above Url static class is theoretical. In practice i user polyglot.js small library to have support to parameters and translation for url - so my Url.to method looks something like that:

export class Url {
    public static to(routingName : string, values?:any) {
        return Lang.t('routing.'+routingName, values);
    }
}

Which use class:

var Polyglot = require('../../../../node_modules/node-polyglot/build/polyglot.min.js');

import { Auth } from '../';
import { en } from './en';
import { pl } from './pl';

export class Lang {
  private static instance = null;
  public polyglot:any;
  private static emergencyLang = 'en';

  constructor() {
      this.polyglot = new Polyglot();
      this.polyglot.extend({
          en,  
          pl,
      });
      if(Lang.instance) return;
      Lang.instance = this;
  }

  public static t(key:string, values?:any) {
      let self = Lang.getInstance();
      let user = Auth.user();
      let userLang = user ? user.lang : (navigator.language || navigator.userLanguage);
      let langKey = userLang + '.'+key;
      if(self.polyglot.has(langKey)) return self.polyglot.t(langKey, values);

      return self.polyglot.t(Lang.emergencyLang + '.'+key, values);
  }


  private static getInstance() {
      if(Lang.instance == null) Lang.instance = new Lang();
      return Lang.instance;
  }

}

For instance in ./en.ts I have:

export const en = {
    routing : {
        login: 'login',
        clients: 'my-clients',
        projects: 'my-projects',
        "project.pages": 'my-projects/%{project_id}/pages',
        ...
    }

    login : "Login"
    ....
}

And similar for other languages.

=== EDIT: AoT support ===

I notice that aboce solution (Url class) not cooperating with AoT. Using command npm run build:aot in angular-starter we will see below error:

Error: Error encountered resolving symbol values statically. Calling function 'Url', function calls are not supported. Consider replacing the function or lambda with a reference to an exported function, resolving symbol ROUTES in...

Because on AoT compilation app.routes.ts file is compiled using metadata js subset . So below I give solution for named routes (with parameters) writen using compatibile with AoT js subset:

export class Url {

    public static to(routingName: string, values?: any) {

        return {
            'clients' : 'favourite-clients/' + values['client_id'],
            'projects' : 'projects/' + values['project_id'] + '/best',
            ...
        }[routingName];
    }

}

May be using some trick in app.routes.ts and above Url.to method it will be also posible to incorporate multilang compatibile with AoT.



回答3:

RC.3 is most recent Angular2 version and the new router V3-alpha7 doesn't support names. Name was removed because it didn't work out with lazy loading of routes.