我想知道在Angular7中是否有一种方法可以为我的路由命名,这样我就可以只调用 [routerLink]="myRouteName"
而不是 [routerLink]="/my/route/path"
。
如果可以,我该如何实现?
我想知道在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中创建(您无需注入)。在您的组件中创建一个公共变量以访问静态类,例如在app.component.ts中创建(您无需注入)。
public routeNames = RouteNames;
那么 app.component.html
将会如下:
<button [routerLink]="routeNames.routeNamesObject['Hello2']">Click to Navigate to Hello</button>
"routeNames.routeNamesObject['...']"
的干净替代方法是定义一个管道(比如说 url
),它可以这样做:routerLink="{{ 'Hello2' | url }}"
。这样你就避免了在每个需要它们的组件中本地定义路由名称的问题。 - Safroninterface NamedRoute implements Route { name: string}
和 type NamedRoutes = NamedRoute[]
,而不是将名称添加到数据属性中,然后使用这些接口。那么路由就会简单地看起来像 {path: "hello", component: HelloComponent, name: "Hello2" }
。 - SafronNamedRouterModule
,在 forRoot
/forChild
方法中注册名称,也可以摆脱使用 routes.forEach(...)
自己注册名称的开销。也许我应该创建一个包... - Safron我是这样做到的(如果有人能告诉我如何删除Array循环,那就更好了):
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>
<a [routerLink]="routerLinkVariable"></a>
export class myComponent {
public routerLinkVariable = "/my/route/path"; // the value of the variable is string!
}
您可以使用常量文件来实现此目的,以便在其他组件中也可以重复使用。
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},
.TS
文件中使用常量变量,然后在视图中使用该变量。我们使用常量文件以提高代码的可用性,否则该URL也可以直接放在该变量中。 - Rohit.007/my/contract/<id>/details/foo
? - Datz在你的类中
public routeName = '/customRoute/myExample'
那么在你的模板中
[routerLink]="routeName"
我认为这应该可以将那个值提取出来,我想这就是你所要求的。只有当customRoute
实际上是你已创建的有效路由名称时,它才能起作用。
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;
}
}
}
}
}
{ path: 'users/:id/edit', component: UserComponent, data: { name: 'edit_user' }}
<a [routerLink]="'edit_user'|path:35">Some link</a>
editUser(){
let userID = // look for user id
this._router.navigate('edit_user', {id: userID});
}