我想知道是否有一种方法可以在 Angular7 中命名我的路线,这样我就可以调用
[routerLink]="myRouteName"
而不是 [routerLink]="/my/route/path"
。
如果是这样,我怎样才能实现这个目标?
考虑到您想要在创建路由配置时配置路由名称。
让我们利用
routes'
数据属性将名称添加到路由中。 (每条路线中的少量额外数据不应影响任何性能)。
但首先,让我们创建一个包含静态属性的类,用于保存路由名称及其实际路径。
export class RouteNames {
public static routeNamesObject = {}
}
现在在您定义了路由的路由组件中,让我们像这样:
const routes: Routes = [
{path: "hello/:id", component: HelloComponent, data: {routeName: "Hello1"}},
{path: "hello", component: HelloComponent, data: { routeName: "Hello2" }}
]
在此变量初始化之后设置 RouteNames 类的静态属性
routes.forEach((eachRoute) => {
RouteNames.routeNamesObject[eachRoute.data.routeName] = eachRoute.path; // now all route paths are added to this prop
})
在组件中创建一个公共变量来访问静态类
就像app.component.ts中一样:(你不需要注入)
public routeNames = RouteNames;
然后
app.component.html
将类似于:
<button [routerLink]="routeNames.routeNamesObject['Hello2']">Click to Navigate to Hello</button>
<a [routerLink]="routerLinkVariable"></a>
因此这个变量(routerLinkVariable)可以在您的类中定义,并且它应该具有如下所示的值
export class myComponent {
public routerLinkVariable = "/my/route/path"; // the value of the variable is string!
}
我设法这样做了(如果有人能告诉我如何删除数组循环,那就更好了):
custom-route.interface.ts -- 这是为我们的路由对象添加名称
export interface ICustomRoute extends Route {
name?: string;
}
在routing.module.ts中(或者你存储路由的任何地方):
const routes: ICustomRoute[] = [
{ path: 'some/random/page1', component: TestComponent, name: 'page1' },
{ path: 'some/random/page2', component: Test2Component, name: 'page2' },
{ path: 'page3', component: Test3Component, name: 'page3' },
];
现在名称正在传递到您的路由模块中,因此现在您必须捕获该名称并处理它。你可以通过多种方式做到这一点,我最终使用了一个指令(我看到@Safron也提到了一个管道)
named-routerlink.directive.ts
@Directive({
selector: 'a[namedRouterLink]'
})
export class NamedRouterLinkDirective extends RouterLinkWithHref{
@Input('namedRouterLink')
set namedRouterLink(val: any) {
const selectedRoute = this.myRoute.config.filter( x => x['name'] == val)[0];
this.routerLink = "/" + selectedRoute['path']
};
constructor(router: Router, route: ActivatedRoute, locationStrategy: LocationStrategy, private myRoute: Router){
super(router, route, locationStrategy)
}
}
然后显然像这样使用:
<a namedRouterLink="page1">Page 1</a>
管道版本:
@Pipe({name: 'getRoute' })
export class RoutePipe implements PipeTransform {
constructor(private router: Router){}
transform(routeName: string): string {
const selectedRoute = this.router.config.filter( x => x['name'] == routeName)[0];
return "/" + selectedRoute['path']
}
}
管道示例:
<a namedRouterLink="{{ 'page1' | getRoute }}">Page 1</a>
您可以使用常量文件,以便它也可以在其他组件中重用。
export const ROUTE_URL = {
myRouteName: '/my/route/path',
};
有多少就多少。
然后在
.TS
上使用该常量并在视图中使用它。
查看:
<a [routerLink]="routerUrls.myRouteName"></a>
.TS:
public routerUrls= ROUTE_URL;
甚至在您的路线文件中
{ path: 'xyz', loadChildren: ROUTE_URL.myRouteName},
在你的班级
public routeName = '/customRoute/myExample'
然后在您的模板中
[routerLink]="routeName"
这应该会体现出该价值,我认为这就是您所要求的。仅当
customRoute
实际上是您创建的有效路线名称时,这才有效。
这很古老但很疯狂,Angular 还不支持开箱即用,当应用程序变得更大并且有很多带有很多斜杠的 URL 时,将很难记住它。
我已经成功创建了一个支持路由命名的管道,它支持路由参数和查询参数,这是代码:
import { Pipe, PipeTransform } from '@angular/core';
import { Router, Route } from '@angular/router';
import {isUndefined} from "util";
@Pipe({
name: 'path'
})
export class RoutingPipe implements PipeTransform {
private _path: string = null;
constructor(
private _router: Router
){}
transform(_route_name: any, params?: {}): any {
this._path = null;
this.findPath(this._router.config, _route_name);
if(this._path == null) throw new Error('No path found for name "'+_route_name+'"!');
if(params){
for (let k in params) {
if (params.hasOwnProperty(k)) {
this._path = this._path.replace(`:${k}`, params[k]);
}
}
}
return this._path;
}
/**
* navigate to component by route name
*
* @param name route name
* @param params route params if exist
*/
navigate(name: string, params?: {}){
this._router.navigate([this.transform(name, params)]);
}
/**
* Find route's full path by name
*
* @param config routes
* @param name route name
* @param parent
*/
findPath(config: Route[], name: String, parent?: string) {
parent = parent || '';
for (let i = 0; i < config.length; i++) {
const route: Route = config[i];
const path = parent + '/' + route.path;
if (route.children) {
// this._path = null;
const currentPath = route.path ? parent + '/' + route.path : parent;
this.findPath(route.children, name, currentPath);
}else{
if(!isUndefined(route.data) && (<any>route.data).name == name){
this._path = path;
}
}
}
}
}
在routing.ts文件中声明它:
{ path: 'users/:id/edit', component: UserComponent, data: { name: 'edit_user' }}
您可以在 html 文件中这样使用它:
<a [routerLink]="'edit_user'|path:35">Some link</a>
也在你的 component.ts 中作为服务(确保将其注入到构造函数中)
editUser(){
let userID = // look for user id
this._router.navigate('edit_user', {id: userID});
}