【问题标题】:Is there a way to name a route in Angular 7?有没有办法在 Angular 7 中命名路线?
【发布时间】:2019-05-05 23:49:39
【问题描述】:

我想知道是否有办法在 Angular7 中命名我的路线,这样我就可以调用 [routerLink]="myRouteName" 而不是 [routerLink]="/my/route/path"

如果是这样,我该如何实现?

【问题讨论】:

  • 使用常量值。
  • 没有任何东西可以直接为路线指定名称。但是,您可以通过创建与您打算使用的名称 (/myRouteName) 相同并且可以重定向到深层路由 (/my/route/path) 的路由来解决问题。
  • 如何确定 routeName?想要在创建路由配置时硬编码?

标签: angular angular-router angular7


【解决方案1】:

考虑到您要在创建路由配置时配置路由名称。

让我们利用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>

【讨论】:

  • 我想过这种方法,但我只是想确保没有其他选择。我想我将不得不坚持这样的事情。您的解决方案很好,但我想知道它是否不会为这个问题带来太多复杂性。只设置一个带有常量的 .ts 文件并在路由模块和组件中使用它不是更好吗?
  • 哦,是的.. 拥有一个带有路径名常量的单独文件要酷得多!我觉得这样更好!在配置路由和在组件中使用它们时使用常量
  • 必须键入"routeNames.routeNamesObject['...']" 的一个干净替代方法是定义一个执行此操作的管道(例如url),例如routerLink="{{ 'Hello2' | url }}"。这样您就不必在需要它们的每个组件中本地定义路由名称。
  • 另外,您可以考虑创建interface NamedRoute implements Route { name: string}type NamedRoutes = NamedRoute[] 并改用这些接口,而不是将名称添加到数据属性。一条路线看起来就像{path: "hello", component: HelloComponent, name: "Hello2" }
  • 创建一个NamedRouterModule,在forRoot/forChild方法中注册名字,也可以省去自己用routes.forEach(...)注册名字的开销。也许我应该创建包...
【解决方案2】:
<a [routerLink]="routerLinkVariable"></a>

所以这个变量(routerLinkVariable)可以在你的类中定义,它应该有一个如下的值

export class myComponent {

     public routerLinkVariable = "/my/route/path"; // the value of the variable is string!
}

【讨论】:

    【解决方案3】:

    您可以为此使用常量文件,以便它也可以在其他组件中重用。

    export const ROUTE_URL = {
        myRouteName: '/my/route/path',
    };
    

    你有多少。

    然后在.TS 上使用该常量并在视图中使用它。

    查看:

    &lt;a [routerLink]="routerUrls.myRouteName"&gt;&lt;/a&gt;

    .TS:

    public routerUrls= ROUTE_URL;

    即使在您的路线文件上

     { path: 'xyz', loadChildren:  ROUTE_URL.myRouteName},
    

    【讨论】:

    • 我们在应用程序中使用相同的设置从后端 API 加载路由。我们可以直接在.TS 中的变量中使用常量,然后可以在视图中使用该变量。我们使用常量文件来提高代码的可用性,否则该 url 也可以直接在该变量中。
    • 我见过这种方法,但使用起来感觉不太舒服。所以我一直在寻找一种可能的“开箱即用”的方式。我想我必须坚持这个。
    • 具有这样 id 的路径的常量看起来如何? /my/contract/&lt;id&gt;/details/foo ?
    【解决方案4】:

    我设法做到了这一点(如果有人能告诉我如何删除 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>
    

    【讨论】:

    • 好吧,我更喜欢指令解决方案,甚至比管道更好:)
    • 晚了,但我非常喜欢这些解决方案!
    【解决方案5】:

    在你的课堂上

    public routeName = '/customRoute/myExample'
    

    然后在你的模板中

    [routerLink]="routeName"
    

    这应该通过这个价值,我认为这就是你所要求的。这仅在 customRoute 实际上是您创建的有效路由名称时才有效。

    【讨论】:

      猜你喜欢
      • 2015-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-04
      • 2012-05-07
      • 2011-07-09
      • 2011-03-26
      相关资源
      最近更新 更多