javascript - Angularで、アクティブルートをどのように判定しますか?
注意: ここには多くの異なる答えがあり、ほとんどの答えは一度は有効でした。実際のところ、Angularチームがルーターを変更するたびに、うまくいく方法も何度か変わっています。最終的にAngularのデフォルトルーターとなるRouter 3.0バージョンは、これらの多くの解決策を壊しますが、それ自体で非常に簡単な解決策を提供します。RC.3以降、推奨される解決策はこの回答に示されているように、[routerLinkActive]を使用することです。
Angular アプリケーション(執筆時点では 2.0.0-beta.0 リリースのもの)で、現在アクティブなルートをどのように確認しますか?
私はBootstrap 4を使用するアプリを作っており、関連するコンポーネントが<router-output>タグで表示されているときに、ナビゲーションリンクやボタンをアクティブとしてマークする方法が必要です。
あるボタンがクリックされたときに自分で状態を維持できることは理解していますが、それでは同じルートに複数の経路(例えば、メインのナビゲーションメニューとメインコンポーネント内のローカルメニューの両方)からアクセスする場合をカバーできません。
ご提案やリンクがあれば助かります。ありがとうございます。
回答 #1
新しい Angular ルーターでは、すべてのリンクに [routerLinkActive]="['your-class-name']" 属性を追加することができます:
<a [routerLink]="['/home']" [routerLinkActive]="['is-active']">Home</a>
または、クラスが1つだけ必要な場合の簡略化された非配列形式:
<a [routerLink]="['/home']" [routerLinkActive]="'is-active'">Home</a>
あるいは、クラスが1つだけ必要な場合は、さらに簡単な形式です:
<a [routerLink]="['/home']" routerLinkActive="is-active">Home</a>
詳細については、ほとんど文書化されていない routerLinkActive ディレクティブを参照してください。(ほとんどは試行錯誤で理解しました。)
更新: routerLinkActive ディレクティブのより良いドキュメントは、こちらで見つけることができます。(以下のコメントで @Victor Hugo Arango A. に感謝します。)
回答 #2
私はこれを別の質問でも答えましたが、これもこの質問に関連しているかもしれないと思います。こちらが元の回答へのリンクです: Angular: パラメータ付きのアクティブルートをどのように判定するか?
現在の場所が正確に何であるかを知らなくても、active クラスを設定しようとしています (ルート名を使用)。これまでのところ私が得た最良の解決策は、Router クラスで利用可能な isRouteActive 関数を使用することです。
router.isRouteActive(instruction): Boolean は、1 つのパラメータとしてルートの Instruction オブジェクトを受け取り、その指示が現在のルートに対して正しいかどうかに応じて true または false を返します。ルートの Instruction は、Router の generate(linkParams: Array) を使用して生成できます。LinkParams は、routerLink ディレクティブに渡される値と全く同じ形式に従います(例: router.isRouteActive(router.generate(['/User', { user: user.id }])))。
これは RouteConfig がこのように見える可能性がある例です (パラメータの使用例を示すために少し調整しました):
@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>
これまで、この問題に対する私の好ましい解決策はこれでした。あなたにも役立つかもしれません。
回答 #3
@alex-correia-santos の回答に対する小さな改善、https://github.com/angular/angular/pull/6407#issuecomment-190179875 に基づく
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>
回答 #4
私はこのリンクで遭遇した問題を解決し、あなたの質問には簡単な解決策があることを発見しました。スタイルには代わりに router-link-active を使用することができます。
@Component({
styles: [`.router-link-active { background-color: red; }`]
})
export class NavComponent {
}
回答 #5
コントローラーに Location オブジェクトを注入し、次のように path() を確認することで、現在のルートを確認できます。
class MyController {
constructor(private location:Location) {}
... location.path(); ...
}
まずそれをインポートすることを確認する必要があります:
import {Location} from "angular2/router";
その後、正規表現を使用して返されるパスにマッチさせ、どのルートがアクティブかを確認できます。Location クラスは、使用している LocationStrategy に関係なく正規化されたパスを返すことに注意してください。したがって、たとえ HashLocationStrategy を使用していても、返されるパスは /foo/bar の形式であり、#/foo/bar ではありません。
回答 #6
アクティブなルートをマークするには、routerLinkActive を使用できます
<a [routerLink]="/user" routerLinkActive="some class list">User</a>
これは他の要素にも適用できます
<div routerLinkActive="some class list">
<a [routerLink]="/user">User</a>
</div>
部分一致もマークする場合は使用してください
routerLinkActive="some class list" [routerLinkActiveOptions]="{ exact: false }"
私の知る限り、exact: false は RC.4 ではデフォルトになります
回答 #7
現在アクティブなルートが何かをどのように判断しますか?
更新: 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
}
もっと見る...
回答 #8
Angular 8の時点で、これは動作します:
<li routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">
<a [routerLink]="['/']">Home</a>
</li>
`{ exact: true }` は URL と完全に一致することを保証します。
回答 #9
型なしの例を追加してみようと思いました:
<input type="hidden" [routerLink]="'home'" routerLinkActive #home="routerLinkActive" />
<section *ngIf="home.isActive"></section>
routerLinkActive 変数はテンプレート変数にバインドされ、その後必要に応じて再利用されます。残念ながら唯一の注意点は、これをすべて <section> 要素に置くことはできないということです。#home はパーサーが <section> に到達する 前に 解決される必要があるためです。
回答 #10
2020年に、[routerLink]を持たない要素にアクティブクラスを設定したい場合は、単純に次のようにできます:
<a
(click)="bookmarks()"
[class.active]="router.isActive('/string/path/'+you+'/need', false)" // <== you need this one. second argument 'false' - exact: true/false
routerLinkActive="active"
[routerLinkActiveOptions]="{ exact: true }"
>
bookmarks
</a>
回答 #11
これはアクティブ/非アクティブなルートに役立ちました:
<a routerLink="/user/bob" routerLinkActive #rla="routerLinkActive" [ngClass]="rla.isActive ? 'classIfActive' : 'classIfNotActive'">
</a>
参照
回答 #12
今は rc.4 と bootstrap 4 を使っていて、これが私には完璧に機能します:
<li class="nav-item" routerLinkActive="active" [routerLinkActiveOptions]="{exact:
true}">
<a class="nav-link" [routerLink]="['']">Home</a>
</li>
これは URL : /home に対して動作します
