角度2 - 检查当前活动路线"名称"

tru*_*k18 15 angular2-routing angular

我有一个带有几个嵌套子视图的Angular 2应用程序.但它会显示在同一页面上router-outlet.

const routes: Routes = [
    {
        path: 'queue/:date/:offset/:type',
        component: BundleListComponent,
        resolve: {
            response: BundleListResolve
        },
        children: [
            {
                path: ':bundleId', component: PointListComponent,
                resolve: {
                    response: PointListResolve
                },
                children: [
                    {
                        path: ':pointId', component: TaskListComponent,
                        resolve: {
                            response: TaskListResolve
                        },
                        children: [
                            {
                                path: ':taskId', component: TaskDetailComponent,
                                resolve: {
                                    response: TaskDetailResolve
                                }
                            },
                            { path: '', component: EmptyComponent }
                        ]
                    },
                    { path: '', component: EmptyComponent }
                ]
            },
            { path: '', component: EmptyComponent }
        ]

    },
    {
        path: 'queue',
        component: QueueRedirectComponent
    }
}
Run Code Online (Sandbox Code Playgroud)

所以基本上我可以通过路线列表

  • /队列
  • /队列/:日期/:偏置/:类型
  • /队列/:日期/:偏置/:类型/:bundleId
  • /队列/:日期/:偏置/:类型/:bundleId /:点名
  • /队列/:日期/:偏置/:类型/:bundleId /:点名/:的TaskID

例如

#/queue/2017-01-05/480/20/57f4c26507b36e3684007b52/1/57fb0abb07b36e39d8e88df8/1
Run Code Online (Sandbox Code Playgroud)

想象一下,你有一个包含一些元素的页面:

  1. 一个UI部分显示了一个电影列表
  2. 当点击电影列表中的项目但显示在同一页面上时,另一部分显示电影细节​​.
  3. 在电影细节上点击角色名称时显示角色细节的另一部分,也显示在同一页面上.
  4. 等等...

基本上,我在查看角色细节时仍然可以点击进入电影列表.

搜索定义每条路线的名称,但似乎所有答案报告此功能已从Angular 2 final中删除.在使用UI路由器的Angular 1中,我可以为每个路由定义名称,并且可以使用内置函数轻松获取路由state.is(ROUTE_NAME).

所以我现在正在做的是基于window.location来获取URL并将此字符串拆分/以获取参数的数量.但它更难以编码.

做同样的经验吗?我如何区分当前活跃的路线?

Sco*_*ott 14

创建一个名为服务ActiveState,将subscribe到更改路由器,使用router.events.subscribe:

import {Injectable} from "@angular/core";
import {Router, ActivatedRoute, NavigationEnd} from "@angular/router";

@Injectable()
export class ActiveState {

  public name : string;

  constructor(router : Router, route : ActivatedRoute)
  {
    router.events.subscribe(event => {
      if(event instanceof NavigationEnd){

        // Traverse the active route tree
        var snapshot = route.snapshot;
        var activated = route.firstChild;
        if(activated != null) {
          while (activated != null) {
            snapshot = activated.snapshot;
            activated = activated.firstChild;
          }
        }

        // Try finding the 'stateName' from the data
        this.name = snapshot.data['stateName'] || "unnamed";
      }
    });
  }

  is(name : string) : boolean
  {
    return this.name === name;
  }
}
Run Code Online (Sandbox Code Playgroud)

然后在你的路线上,我们在路由的data参数上添加一个简单的值,stateName为我们想要命名的每个状态调用:

const routes: Routes = [
{
    path: 'queue/:date/:offset/:type',
    component: BundleListComponent,
    resolve: { response: BundleListResolve }
    data: { stateName: 'Bundle' },
    children: [
        {
            path: ':bundleId', component: PointListComponent,
            resolve: { response: PointListResolve },
            data: { stateName: 'Point'}
        }
    ...
Run Code Online (Sandbox Code Playgroud)

然后,当您注入时,state : ActiveState您可以简单地测试该值state.is("Point")


Pie*_*Duc 5

我相信Scott的答案存在问题,他在服务的构造函数中使用了ActivatedRoute.此路线不会更新.

我想到了另一个可能会让你感兴趣的解决方案.它再次归结为使用data路由上的属性,但现在使用另一个解析服务:

你将需要RouterConfig这样的,你添加的每个路由state: StateResolve和包含州名的数据对象:

const routes: RouterConfig = [{
    path: 'queue/:date/:offset/:type',
    component: BundleListComponent,
    resolve: {
       response: BundleListResolve,
       state: StateResolve
    },
    data: {
       state: 'Bundle'
    },
    ...
]
Run Code Online (Sandbox Code Playgroud)

不要忘记将StateResolve服务添加到providers数组中

您的StateResolve服务将如下所示:

@Injectable()
export class StateResolve implements Resolve<string> {

   constructor(private stateService: StateService) {}

   resolve(route: ActivatedRouteSnapshot): string {
       let state: string = route.data['state']
       this.stateService.setState(state);
       return state;
   }
}
Run Code Online (Sandbox Code Playgroud)

显然你需要一个StateServicesetState方法,但我想从这里开始就是不言自明的.

也许使用resolve警卫有点古怪,但如果你考虑一下,你就是在展示路线之前试图解析数据.在这种情况下,数据变量内部的状态,因此使用它Resolve来访问data属性是有意义的