web-dev-qa-db-ja.com

Angularでは、アクティブルートをどのように決定しますか?

注: ここにはさまざまな答えがあり、そのほとんどは一度に有効になっています。実際のところ、Angularチームがルーターを変更するにつれて、機能が何度も変更されています。 Angularで最終的に the routerになるRouter 3.0バージョンは、これらの解決策の多くを打ち破りますが、非常に単純な独自の解決策を提供します。 RC.3では、推奨される解決策は この回答 に示すように[routerLinkActive]を使用することです。

Angularアプリケーション(これを書いている時点で2.0.0-beta.0リリースで現在)では、どのようにして現在アクティブなルートが何であるかを判断しますか?

私はBootstrap 4を使用するアプリを開発しています。関連するコンポーネントが<router-output>タグで表示されているときにナビゲーションリンク/ボタンをアクティブとしてマークする方法が必要です。

ボタンの1つがクリックされたときに自分の状態を維持することはできますが、同じルートに複数のパスがある場合はカバーされません(メインナビゲーションメニューとメインコンポーネントのローカルメニュー) ).

任意の提案やリンクをいただければ幸いです。ありがとう。

244
Michael Oryl

新しい Angular router を使用すると、すべてのリンクに[routerLinkActive]="['your-class-name']"属性を追加できます。

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

クラスが1つだけ必要な場合は、単純化された非配列形式になります。

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

詳細については 文書化の不十分なrouterLinkActiveディレクティブ を参照してください。 (私は主にこれを試行錯誤で考え出しました。)

更新:routerLinkActiveディレクティブに関するより良いドキュメントが、 here に見つかりました。 (以下のコメントで@Victor Hugo Arango A.に感謝します。)

292
jessepinho

私は別の質問でこれに答えました、しかし私はそれが同様にこれに関連しているかもしれないと思います。これが元の答えへのリンクです。 Angular 2:パラメータを使用してアクティブルートを決定する方法

私は設定しようとしてきました 活動的 現在の場所を正確に知る必要なしにクラス (ルート名を使用)。これまでに得た最良の解決策はRouterクラスで利用可能な関数 isRouteActive を使うことです。

router.isRouteActive(instruction): Booleanは、ルートのInstructionオブジェクトである1つのパラメータを取り、その命令が現在のルートに当てはまるかどうかにかかわらずtrueまたはfalseを返します。 Instructiongenerate(linkParams:Array) を使用して、ルートRouterを生成できます。 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' },
])

そしてその 見る このようになります:

<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>

これはこれまでのところ問題のための私の好ましい解決策でした、それはあなたのためにも役立つかもしれません。

65
Alex Santos

私はこの link で遭遇した問題を解決しました、そして私はあなたの質問に対する簡単な解決策があることを知ります。あなたのスタイルでは代わりにrouter-link-activeを使うことができます。

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

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>
32
tomaszbak

あなたのコントローラにLocationオブジェクトを挿入してpath()をチェックすることで現在のルートをチェックすることができます。

class MyController {
    constructor(private location:Location) {}

    ...  location.path(); ...
}

必ず最初にインポートしてください。

import {Location} from "angular2/router";

その後、どのルートがアクティブであるかを確認するために返されるパスと照合するために正規表現を使用できます。 Locationクラスは、使用しているLocationStrategyに関係なく、正規化されたパスを返します。 HashLocationStragegyを使っていても、返されるパスは/foo/bar - #/foo/barの形式になります。

28
Jason Teplitz

どのように現在アクティブなルートが何であるか判別しますか。

更新:Angular 2.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
}

もっと見る...

16
Ankit Singh

アクティブな経路をマークするにはrouterLinkActiveを使うことができます

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

これは他の要素でも同様に機能します。

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

部分一致の場合 もuseとマークする必要があります

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

私の知る限りでは、RC_4ではexact: falseがデフォルトになる予定です。

9

今私はブートストラップ4でrc.4を使用しています、そしてこれは私にとって完璧に働きます:

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

これはurlでうまくいくでしょう:/ home

7
Artem Zinoviev

以下は、現在のルートに応じてRouteDataを使用してmenuBarアイテムをスタイルする方法です。

RouteConfigはタブ付きのデータ(現在のルート)を含みます。

@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
Ivan

これはnullルートパスを考慮に入れたAngular version 2.0.0-rc.1にアクティブなルートスタイルを追加するための完全な例です(例:path: '/'

app.component.ts - >ルート

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
Levi Fuller

Angular 2 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
lukaville

Router in Angular 2 RCでは、isRouteActiveおよびgenerateメソッドを定義していません。

urlTree - 現在のURLツリーを返します。

createUrlTree(commands: any[], segment?: RouteSegment) - 現在のURLツリーに一連のコマンドを適用し、新しいURLツリーを作成します。

フォローしてみてください

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

注意してください、routeSegment : RouteSegmentはコンポーネントのコンストラクタに挿入されなければなりません。

5
tchelidze

TypeScriptを使用しない例を追加すると思いました。

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

routerLinkActive変数はテンプレート変数にバインドされ、必要に応じて再利用されます。残念ながら、唯一の注意点は、<section>を解決する必要があるため、#home要素にすべてを含めることはできないということです。prior<section>をヒットするパーサーに対して。

5
Zze

リンクがあり、いくつかのクラスを適用したい場合は、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
pleerock

別の回避策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>
4
shakee93

Angular 2 RC 2では、この単純な実装を使用できます。

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

これは、一致するURLを持つ要素にクラスactiveを追加します。それについての詳細を読む ここ

4

以下は、これまでにリリースされたAngular 2 RCバージョンのすべてのバージョンに対するこの質問に対する回答です。

RC4およびRC3

リンクまたはリンクの先祖にクラスを適用する場合

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

/ homeはURLであり、ルーターv3ではRouteオブジェクトにnameプロパティが存在しないため、ルートの名前ではありません。

RouterLinkActiveディレクティブの詳細については、この link を参照してください。

現在のルートに基づいてクラスをdivに適用する場合

  • ルーターをコンポーネントのコンストラクタに注入します。
  • 比較のためにユーザーrouter.url。

例えば

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

RC2およびRC1

Router.isRouteActiveとclass。*の組み合わせを使用してください。例えば、Home Routeに基づいてアクティブクラスを適用すること。

名前とURLの両方をrouter.generateに渡すことができます。

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

Angular version 4以降の場合、複雑な解決策を使用する必要はありません。単に[routerLinkActive]="'is-active'"を使うことができます。

ブートストラップ4ナビゲーションリンクの例

    <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>
4
asmmahmud

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
Anees Dhansey

受け入れられた回答のコメントの1つで述べられているように、routerLinkActiveディレクティブは実際の<a>タグのコンテナにも適用できます。

そのため、例えば Twitterのブートストラップタブを使用する の場合、リンクを含む<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>タグを探します。

3
Pierre Henry

Angular 5ユーザー向けの簡単な解決策は、リストアイテムにrouterLinkActiveを追加するだけです。

routerLinkActiveディレクティブは、routerLinkディレクティブを介した経路に関連付けられています。

次のように、ルートが現在アクティブになっている場合、それはアタッチされている要素に追加されるクラスの配列を入力として取ります。

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

現在ホームルートを表示している場合、上記はアンカータグにactiveのクラスを追加します。

Demo

1
Prasanth Jaya

私はAngular 2で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 ){}
}
1
Ben Thielker

私のアクティブな状態/タブにCSSを追加したいとしましょう。ルーティングリンクをアクティブにするには、 routerLinkActive を使用します。

注意: 'active'は私のクラス名です

<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>
1
UniCoder

Angular 8以降、これは機能します。

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

{ exact: true }は、URLと一致することを確認します。

0
John Kennedy

.tsにRouterLinkActiveをインポートすることから始めます。

'@ angular/router'から{RouterLinkActive}をインポートします。

今すぐあなたのHTMLでRouterLinkActiveを使用してください

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

このリンクがアクティブになったりクリックされたりすると、インスペクション中にこのクラスがスパン上に表示されるので、クラス "class_Name"にCSSを指定します。

0
T. Shashwat

純粋なHTMLテンプレート

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

また、Angularの最新バージョンでは、router.isActive(routeNameAsString)をチェックするだけで済みます。たとえば、次の例を参照してください。

 <div class="collapse navbar-collapse" id="navbarNav">
    <ul class="navbar-nav">
      <li class="nav-item" [class.active] = "router.isActive('/dashboard')">
        <a class="nav-link" href="#">داشبورد <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item" [class.active] = "router.isActive(route.path)" *ngFor="let route of (routes$ | async)">
        <a class="nav-link" href="javascript:void(0)" *ngIf="route.childRoutes && route.childRoutes.length > 0"
          [matMenuTriggerFor]="menu">{{route.name}}</a>
        <a class="nav-link" href="{{route.path}}"
          *ngIf="!route.childRoutes || route.childRoutes.length === 0">{{route.name}}</a>
        <mat-menu #menu="matMenu">
          <span *ngIf="route.childRoutes && route.childRoutes.length > 0">
            <a *ngFor="let child of route.childRoutes" class="nav-link" href="{{route.path + child.path}}"
              mat-menu-item>{{child.name}}</a>
          </span>
        </mat-menu>
      </li>
    </ul>
    <span class="navbar-text mr-auto">
      <small>سلام</small> {{ (currentUser$ | async) ? (currentUser$ | async).firstName : 'کاربر' }}
      {{ (currentUser$ | async) ? (currentUser$ | async).lastName : 'میهمان' }}
    </span>
  </div>

また、コンポーネントにルーターを挿入することを忘れないようにしてください。

0
ConductedClever

角度付きルーター^3.4.7を使用していますが、routerLinkActiveディレクティブに問題があります。

同じURLに複数のリンクがあり、常に更新されていないように見える場合は機能しません。

@tomaszbakの答えに触発された私は 小さなコンポーネントを作成しました 仕事をするために/

0
RPDeshaies