非常に奇妙な問題があります:index.html
<navigation-menu *ngIf="isLoggedIn"></navigation-menu>
<div class="content-wrapper" [ngClass]="{'fullContent' : !isLoggedIn}">
<section class="content">
<router-outlet></router-outlet>
</section>
</div>
ナビゲーションメニューは、ナビゲーションメニューのコンポーネントです。ルーターアウトレットコンテンツには、「アセット」と呼ばれるコンポーネントがあります。
資産コンポーネントで私がしたこと:
import { ActivatedRoute}from "@angular/router";
constructor(private route: ActivatedRoute){}
public ngOnInit(): void {
this.route.params.subscribe(params => {
const id = params["id"];
}
これは機能し、ルートのパラメーター(一種の「asset /:id」)を取得します。
ナビゲーションメニューコンポーネント(ルーターアウトレットの「外側」)とcontextserviceと呼ばれるグローバルサービスで同じことを試しました。上記と同じコードですが、ルート変更でもトリガーされません。現在のルーターのスナップショットを取得しようとすると
const strId = this.route.snapshot.params["id"];
navigationEndイベントがトリガーされた後も同じ結果になります。paramsは空のオブジェクトであるため、strIdは未定義です。
アセットコンポーネントでのみ機能します。これは意図したとおりに機能していますか?
私の意図は、すべてのroute(-params)の変更をリッスンしているグローバルサービス(またはnavメニューのような「グローバル」コンポーネント)からイベントをトリガーすることでした。
私の唯一の解決策は、NavigationEndイベントごとに完全なURLを解析することですが、これは適切ではありません...または各子コンポーネント(ルーターアウトレット)自体のparams変更を処理することです。
たぶん私は理解の基本的なエラーがあります...
ありがとう
受け入れられた答えからの解決策:
this.router.events.subscribe(val => {
if (val instanceof RoutesRecognized) {
var strId = val.state.root.firstChild.params["id"];
}});
RoutesRecognizedをangular router !!からインポートすることを忘れないでください。
ルーターによって追加されたコンポーネントは、ルーターセグメント(ActivatedRoute
)を渡しますが、サービスにはアクティブ化されたルートはありません。 router.eventsにサブスクライブし、ルートツリー(router.firstChild ... `)を走査して、必要な特定のルートシーケンスからパラメーターを取得できます。
以下はangularのサービスです。
import {Injectable} from '@angular/core';
import {ActivatedRoute, NavigationEnd, NavigationExtras, ParamMap, Router} from "@angular/router";
import {RouterExtensions} from "nativescript-angular/router";
import {NavigationOptions} from "nativescript-angular/router/ns-location-strategy";
import {Observable} from "rxjs/Observable";
import {first} from "rxjs/operators/first";
import {filter} from "rxjs/operators/filter";
import {map} from "rxjs/operators/map";
import {switchMap} from "rxjs/operators/switchMap";
import {unRegisterAndroidOnBack} from "../../utils/view.utils";
@Injectable()
export class RoutingService
{
constructor(private routerExtensions: RouterExtensions, private route: ActivatedRoute, private router: Router)
{
}
public getActivatedRouteParameter(paramName: string): Observable<ParamMap>
{
return this.router.events.pipe(filter(e => e instanceof NavigationEnd),
map((): ActivatedRoute =>
{
let route = this.route;
while (route.firstChild)
{
route = route.firstChild;
}
return route;
}),
filter((route: ActivatedRoute) => route.outlet === 'primary'),
switchMap((route: ActivatedRoute) => route.paramMap) , first());
}
実際には、activatedRouteは正しく更新されていますが、その中にすべてのツリーがあります。したがって、route.firstChildの内部を最後まで進むと、最終的に最後のルートが見つかります。これをdeeperActivatedRoute(route.firstChild ... route.firstChildの内部)と呼びます。
だから私がやったことは、deeperRouteを追跡するサービスを作成し、常にアクセス可能にすることです
import { Injectable } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
@Injectable()
export class ActivatedRouteService {
private _deeperActivatedRoute: ActivatedRoute;
get deeperActivatedRoute(): ActivatedRoute {
return this._deeperActivatedRoute;
}
constructor(private router: Router, private route: ActivatedRoute) {}
init(): void {
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
// Traverse the active route tree
let activatedChild = this.route.firstChild;
if (activatedChild != null) {
let nextActivatedChild;
while (nextActivatedChild != null) {
nextActivatedChild = activatedChild.firstChild;
if (nextActivatedChild != null) {
activatedChild = activatedChild.firstChild;
}
}
}
this._deeperActivatedRoute = activatedChild || this.route;
}
});
}
}
その後、app.component.tsでサービスを開始します(常に追跡することを確認するためだけです)
export class AppComponent {
constructor(private activatedRouteService: ActivatedRouteService) {
this.activatedRouteService.init();
}
}
そして最後に、あなたがどこにいてもあなたのルートを取ります:
export class ForbiddenInterceptor implements HttpInterceptor {
constructor(private activatedRouteService: ActivatedRouteService) { }
doYourStuff(): void {
//you'll have the correct activatedRoute here
this.activatedRouteService.deeperActivatedRoute;
}
}
質問に答えるには、deeperActivatedRouteを使用して、コンポーネントで行うのと同じように、通常はsnapshop.urlを確認します。