首页 文章

在Angular中,您如何确定活动路线?

提问于
浏览
225

NOTE: 这里有许多不同的答案,大多数都是有效的 . 事实是,当Angular团队改变其路由器时,有效的改变了很多次 . 最终将成为Angular中的 the 路由器的Router 3.0版本打破了许多这些解决方案,但提供了一个非常简单的解决方案 . 从RC.3开始,首选解决方案是使用 [routerLinkActive] ,如this answer所示 .

在Angular应用程序中(当我写这篇文章时,目前在2.0.0-beta.0版本中),您如何确定当前活动路由是什么?

我正在开发一个使用Bootstrap 4的应用程序,我需要一种方法将导航链接/按钮标记为活动,当它们的相关组件显示在 <router-output> 标记中时 .

我意识到,当点击其中一个按钮时,我可以自己维护状态,但这不会涵盖将多条路径放入同一路径的情况(例如主导航菜单以及主要组件中的本地菜单) ) .

任何建议或链接将不胜感激 . 谢谢 .

26 回答

  • 65

    使用新的Angular router,您可以为所有链接添加 [routerLinkActive]="['your-class-name']" 属性:

    <a [routerLink]="['/home']" [routerLinkActive]="['is-active']">Home</a>
    

    或者简化的非数组格式(如果只需要一个类):

    <a [routerLink]="['/home']" [routerLinkActive]="'is-active'">Home</a>
    

    有关详细信息,请参阅poorly documented routerLinkActive directive . (我主要通过反复试验来解决这个问题 . )

    更新:现在可以找到 routerLinkActive 指令的更好文档here . (感谢@Victor Hugo Arango A.在下面的评论中 . )

  • 33

    我've replied this in another question but I believe it might be relevant to this one as well. Here'是原始答案的链接:Angular 2: How to determine active route with parameters?

    我一直试图设置 active 类,而不必确切知道当前位置是什么(使用路由名称) . 到目前为止,我所使用的最佳解决方案是使用 Router 类中提供的函数isRouteActive .

    router.isRouteActive(instruction): Boolean 接受一个参数,它是一个路径 Instruction 对象,并返回 truefalse ,无论该指令对于当前路由是否成立 . 您可以使用 Routergenerate(linkParams: Array)生成路径 Instruction . LinkParams遵循与传递给routerLink指令的值完全相同的格式(例如 router.isRouteActive(router.generate(['/User', { user: user.id }])) ) .

    这就是 RouteConfig 的样子(我已经调整了一下以显示params的用法):

    @RouteConfig([
      { path: '/', component: HomePage, name: 'Home' },
      { path: '/signin', component: SignInPage, name: 'SignIn' },
      { path: '/profile/:username/feed', component: FeedPage, name: 'ProfileFeed' },
    ])
    

    View 看起来像这样:

    <li [class.active]="router.isRouteActive(router.generate(['/Home']))">
       <a [routerLink]="['/Home']">Home</a>
    </li>
    <li [class.active]="router.isRouteActive(router.generate(['/SignIn']))">
       <a [routerLink]="['/SignIn']">Sign In</a>
    </li>
    <li [class.active]="router.isRouteActive(router.generate(['/ProfileFeed', { username: user.username }]))">
        <a [routerLink]="['/ProfileFeed', { username: user.username }]">Feed</a>
    </li>
    

    到目前为止,这是我遇到问题的首选解决方案,它也可能对您有所帮助 .

  • 7

    我解决了我在link中遇到的问题,我发现你的问题有一个简单的解决方案 . 您可以在样式中使用 router-link-active .

    @Component({
       styles: [`.router-link-active { background-color: red; }`]
    })
    export class NavComponent {
    }
    
  • 4

    基于https://github.com/angular/angular/pull/6407#issuecomment-190179875 @ alex-correia-santos答案的小改进

    import {Router, RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
    // ...
    export class App {
      constructor(private router: Router) {
      }
    
      // ...
    
      isActive(instruction: any[]): boolean {
        return this.router.isRouteActive(this.router.generate(instruction));
      }
    }
    

    并像这样使用它:

    <ul class="nav navbar-nav">
        <li [class.active]="isActive(['Home'])">
            <a [routerLink]="['Home']">Home</a>
        </li>
        <li [class.active]="isActive(['About'])">
            <a [routerLink]="['About']">About</a>
        </li>
    </ul>
    
  • 0

    您可以通过将 Location 对象注入控制器并检查 path() 来检查当前路由,如下所示:

    class MyController {
        constructor(private location:Location) {}
    
        ...  location.path(); ...
    }
    

    您必须首先确保导入它:

    import {Location} from "angular2/router";
    

    然后,您可以使用正则表达式与返回的路径进行匹配,以查看哪条路由处于活动状态 . 请注意, Location 类返回一个规范化路径,无论您使用 HashLocationStragegy 使用 HashLocationStragegy 返回的路径仍然是 /foo/bar not #/foo/bar

  • 6

    您如何确定当前活动路线是什么?

    UPDATE: updated as per Angular2.4.x

    constructor(route: ActivatedRoute) {
       route.snapshot.params; // active route's params
    
       route.snapshot.data; // active route's resolved data
    
       route.snapshot.component; // active route's component
    
       route.snapshot.queryParams // The query parameters shared by all the routes
    }
    

    see more...

  • 0

    要标记活动路径,可以使用 routerLinkActive

    <a [routerLink]="/user" routerLinkActive="some class list">User</a>
    

    这也适用于其他元素

    <div routerLinkActive="some class list">
      <a [routerLink]="/user">User</a>
    </div>
    

    如果partial matches也应该标记使用

    routerLinkActive="some class list" [routerLinkActiveOptions]="{ exact: false }"
    

    据我所知 exact: false 将成为RC.4的默认值

  • 28

    下面是使用RouteData根据当前路径设置menuBar项的样式的方法:

    RouteConfig包含带tab的数据(当前路由):

    @RouteConfig([
      {
        path: '/home',    name: 'Home',    component: HomeComponent,
        data: {activeTab: 'home'},  useAsDefault: true
      }, {
        path: '/jobs',    name: 'Jobs',    data: {activeTab: 'jobs'},
        component: JobsComponent
      }
    ])
    

    一块布局:

    <li role="presentation" [ngClass]="{active: isActive('home')}">
        <a [routerLink]="['Home']">Home</a>
      </li>
      <li role="presentation" [ngClass]="{active: isActive('jobs')}">
        <a [routerLink]="['Jobs']">Jobs</a>
      </li>
    

    类:

    export class MainMenuComponent {
      router: Router;
    
      constructor(data: Router) {
        this.router = data;
      }
    
      isActive(tab): boolean {
        if (this.router.currentInstruction && this.router.currentInstruction.component.routeData) {
          return tab == this.router.currentInstruction.component.routeData.data['activeTab'];
        }
        return false;
      }
    }
    
  • 6

    这是在Angular版本 2.0.0-rc.1 中添加活动路由样式的完整示例,其中考虑了空根路径(例如 path: '/'

    app.component.ts -> Routes

    import { Component, OnInit } from '@angular/core';
    import { Routes, Router, ROUTER_DIRECTIVES } from '@angular/router';
    import { LoginPage, AddCandidatePage } from './export';
    import {UserService} from './SERVICES/user.service';
    
    @Component({
      moduleId: 'app/',
      selector: 'my-app',
      templateUrl: 'app.component.html',
      styleUrls: ['app.component.css'],
      providers: [UserService],
      directives: [ROUTER_DIRECTIVES]
    })
    
    @Routes([
      { path: '/', component: AddCandidatePage },
      { path: 'Login', component: LoginPage }
    ])
    export class AppComponent  { //implements OnInit
    
      constructor(private router: Router){}
    
      routeIsActive(routePath: string) {
         let currentRoute = this.router.urlTree.firstChild(this.router.urlTree.root);
         // e.g. 'Login' or null if route is '/'
         let segment = currentRoute == null ? '/' : currentRoute.segment;
         return  segment == routePath;
      }
    }
    

    app.component.html

    <ul>
      <li [class.active]="routeIsActive('Login')"><a [routerLink]="['Login']" >Login</a></li>
      <li [class.active]="routeIsActive('/')"><a [routerLink]="['/']" >AddCandidate</a></li>
    </ul>
    <route-outlet></router-outlet>
    
  • 6

    Angular2 RC 4的解决方案:

    import {containsTree} from '@angular/router/src/url_tree';
    import {Router} from '@angular/router';
    
    export function isRouteActive(router: Router, route: string) {
       const currentUrlTree = router.parseUrl(router.url);
       const routeUrlTree = router.createUrlTree([route]);
       return containsTree(currentUrlTree, routeUrlTree, true);
    }
    
  • 6

    现在我正在使用rc.4和bootstrap 4,这个对我来说非常适合:

    <li class="nav-item" routerLinkActive="active" [routerLinkActiveOptions]="{exact:
    true}">
        <a class="nav-link" [routerLink]="['']">Home</a>
    </li>
    

    这适用于url:/ home

  • 1

    Angular 2 RC中的Router不再定义 isRouteActivegenerate 方法 .

    urlTree - 返回当前的url树 . createUrlTree(命令:any [],segment?:RouteSegment) - 将一组命令应用于当前url树并创建一个新的url树 .

    试试以下

    <li 
    [class.active]=
    "router.urlTree.contains(router.createUrlTree(['/SignIn', this.routeSegment]))">
    

    注意, routeSegment : RouteSegment 必须注入组件的构造函数中 .

  • 1

    Router类的实例实际上是一个Observable,它每次更改时都会返回当前路径 . 我是这样做的:

    export class AppComponent implements OnInit { 
    
    currentUrl : string;
    
    constructor(private _router : Router){
        this.currentUrl = ''
    }
    
    ngOnInit() {
        this._router.subscribe(
            currentUrl => this.currentUrl = currentUrl,
            error => console.log(error)
        );
    }
    
    isCurrentRoute(route : string) : boolean {
        return this.currentUrl === route;
     } 
    }
    

    然后在我的HTML中:

    <a [routerLink]="['Contact']" class="item" [class.active]="isCurrentRoute('contact')">Contact</a>
    
  • 3

    另一种解决方法 . 在Angular Router V3 Alpha中更容易 . 通过注入路由器

    import {Router} from "@angular/router";
    
    export class AppComponent{
    
        constructor(private router : Router){}
    
        routeIsActive(routePath: string) {
            return this.router.url == routePath;
        }
    }
    

    用法

    <div *ngIf="routeIsActive('/')"> My content </div>
    
  • 5

    在Angular2 RC2中,您可以使用这个简单的实现

    <a [routerLink]="['/dashboard']" routerLinkActive="active">Dashboard</a>
    

    这会将类 active 添加到元素中匹配的网址,了解更多相关信息here

  • 4

    以下是迄今为止发布的Angular 2 RC版本的所有版本的问题的答案:

    RC4 and RC3

    用于将类应用于链接或链接的祖先:

    <li routerLinkActive="active"><a [routerLink]="['/home']">Home</a></li>
    

    / home应该是URL而不是路由名称,因为自路由器v3起,Route对象上不再存在name属性 .

    有关此link的routerLinkActive指令的更多信息 .

    根据当前路线将类应用于任何div:

    • 将路由器注入组件的构造函数 .

    • 用户router.url进行比较 .

    例如

    <nav [class.transparent]="router.url==('/home')">
    </nav>
    

    RC2 and RC1

    使用router.isRouteActive和class . *的组合 . 例如,根据Home Route应用活动类 .

    名称和URL都可以传递给router.generate .

    <li [class.active]="router.isRouteActive(router.generate(['Home']))">
        <a [routerLink]="['Home']" >Home</a>
    </li>
    
  • 4

    纯html模板就好

    <a [routerLink]="['/home']" routerLinkActive="active">Home</a>
     <a [routerLink]="['/about']" routerLinkActive="active">About us</a>
     <a [routerLink]="['/contact']" routerLinkActive="active">Contacts</a>
    
  • 0

    首先在.ts中导入RouterLinkActive

    从'@ angular / router'导入;

    现在在HTML中使用RouterLinkActive

    <span class="" routerLink ="/some_path" routerLinkActive="class_Name">Value</span></a>
    

    为class“class_Name”提供一些css,因为当这个链接被激活/点击时,你会在检查时找到这个类 .

  • 3

    在简单的情况下使用 routerLinkActive 是好的,当有链接并且您想要应用某些类时 . 但是在更复杂的情况下,您可能没有routerLink或者您需要更多东西,您可以创建并使用 pipe

    @Pipe({
        name: "isRouteActive",
        pure: false
    })
    export class IsRouteActivePipe implements PipeTransform {
    
        constructor(private router: Router,
                    private activatedRoute: ActivatedRoute) {
        }
    
        transform(route: any[], options?: { queryParams?: any[], fragment?: any, exact?: boolean }) {
            if (!options) options = {};
            if (options.exact === undefined) options.exact = true;
    
            const currentUrlTree = this.router.parseUrl(this.router.url);
            const urlTree = this.router.createUrlTree(route, {
                relativeTo: this.activatedRoute,
                queryParams: options.queryParams,
                fragment: options.fragment
            });
            return containsTree(currentUrlTree, urlTree, options.exact);
        }
    }
    

    然后:

    <div *ngIf="['/some-route'] | isRouteActive">...</div>
    

    并且不要忘记在管道依赖项中包含管道;)

  • 4

    对于Angular版本4,您不需要使用任何复杂的解决方案 . 你可以简单地使用 [routerLinkActive]="'is-active'" .

    有关bootstrap 4 nav链接的示例:

    <ul class="navbar-nav mr-auto">
          <li class="nav-item" routerLinkActive="active">
            <a class="nav-link" routerLink="/home">Home</a>
          </li>
          <li class="nav-item" routerLinkActive="active">
            <a class="nav-link" routerLink="/about-us">About Us</a>
          </li>
          <li class="nav-item" routerLinkActive="active">
            <a class="nav-link " routerLink="/contact-us">Contact</a>
          </li>
        </ul>
    
  • 29

    正如在接受的答案的一个评论中所提到的, routerLinkActive 指令也可以应用于实际 <a> 标签的容器 .

    例如 with Twitter Bootstrap tabs ,其中活动类应该应用于包含链接的 <li> 标记:

    <ul class="nav nav-tabs">
        <li role="presentation" routerLinkActive="active">
            <a routerLink="./location">Location</a>
        </li>
        <li role="presentation" routerLinkActive="active">
            <a routerLink="./execution">Execution</a>
        </li>
    </ul>
    

    很简约 !我想该指令检查标记的内容并查找带有 routerLink 指令的 <a> 标记 .

  • 4

    只是想我会添加一个不使用任何打字稿的例子:

    <input type="hidden" [routerLink]="'home'" routerLinkActive #home="routerLinkActive" />
    <section *ngIf="home.isActive"></section>
    

    routerLinkActive 变量绑定到模板变量,然后根据需要重新使用 . 不幸的是唯一需要注意的是,你不能在 <section> 元素上拥有这一切,因为 #home 需要解析 prior 到解析器 <section> .

  • 15

    我正在寻找一种方法来使用Angular2的Twitter Bootstrap样式导航,但无法将 active 类应用于所选链接的父元素 . 发现@ alex-correia-santos的解决方案完美无缺!

    包含选项卡的组件必须导入路由器并在其构造函数中定义它,然后才能进行必要的调用 .

    这是我的实现的简化版本......

    import {Component} from 'angular2/core';
    import {Router, RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
    import {HomeComponent} from './home.component';
    import {LoginComponent} from './login.component';
    import {FeedComponent} from './feed.component';
    
    @Component({
      selector: 'my-app',
      template: `
        <ul class="nav nav-tabs">
          <li [class.active]="_r.isRouteActive(_r.generate(['Home']))">
            <a [routerLink]="['Home']">Home</a>
          </li>
          <li [class.active]="_r.isRouteActive(_r.generate(['Login']))">
            <a [routerLink]="['Login']">Sign In</a>
          </li>
          <li [class.active]="_r.isRouteActive(_r.generate(['Feed']))">
            <a [routerLink]="['Feed']">Feed</a>
          </li>
        </ul>`,
      styleUrls: ['app/app.component.css'],
      directives: [ROUTER_DIRECTIVES]
    })
    @RouteConfig([
      { path:'/', component:HomeComponent, name:'Home', useAsDefault:true },
      { path:'/login', component:LoginComponent, name:'Login' },
      { path:'/feed', component:FeedComponent, name:'Feed' }
    ])
    export class AppComponent {
      title = 'My App';
      constructor( private _r:Router ){}
    }
    
  • 4

    假设您要将CSS添加到我的活动状态/选项卡 . 使用 routerLinkActive 激活路由链接 .

    注意:'active'在这里是我的 class 名称

    <style>
       .active{
           color:blue;
         }
    </style>
    
      <a routerLink="/home" [routerLinkActive]="['active']">Home</a>
      <a routerLink="/about" [routerLinkActive]="['active']">About</a>
      <a routerLink="/contact" [routerLinkActive]="['active']">Contact</a>
    
  • 270

    我正在使用角度路由器 ^3.4.7 ,我仍然遇到 routerLinkActive 指令的问题 .

    如果您有多个具有相同网址的链接,并且它似乎不会一直刷新,则它无法正常工作 .

    受到@tomaszbak答案的启发,我创建了一个little component来完成这项工作

  • 0

    angular 5用户的简单解决方案是,只需将 routerLinkActive 添加到列表项 .

    routerLinkActive 指令通过 routerLink 指令与路由关联 .

    它将一个类数组作为输入,如果它的路由当前处于活动状态,它将添加到它所附加的元素,如下所示:

    <li class="nav-item"
        [routerLinkActive]="['active']">
      <a class="nav-link"
         [routerLink]="['home']">Home
      </a>
    </li>
    

    如果我们当前正在查看归属路由,则上面将向锚标记添加一类活动 .

    Demo

相关问题