子ルートから親ルートに移動するにはどうすればよいですか?


94

私の問題は非常に古典的です。の背後にあるアプリケーションのプライベート部分がありますlogin form。ログインが成功すると、管理アプリケーションの子ルートに移動します。

私の問題はglobal navigation menu、ルーターが私のAdminComponent代わりに私のでルーティングしようとするため、を使用できないことAppCompomentです。だから私のナビゲーションは壊れています。

もう1つの問題は、誰かがURLに直接アクセスしたい場合、親の「ログイン」ルートにリダイレクトしたいということです。しかし、私はそれを機能させることはできません。これらの2つの問題は似ているように私には思えます。

それをどのように行うことができるか考えていますか?


3
コードを追加してください
Jiang YD 2016年

回答:


157

リンク/ HTMLが必要ですか、それとも命令型/コードでルーティングしますか?

リンク:RouterLinkディレクティブは、提供されたリンクを常に現在のURLへのデルタとして扱います。

[routerLink]="['/absolute']"
[routerLink]="['../../parent']"
[routerLink]="['../sibling']"
[routerLink]="['./child']"     // or
[routerLink]="['child']" 

// with route param     ../../parent;abc=xyz
[routerLink]="['../../parent', {abc: 'xyz'}]"
// with query param and fragment   ../../parent?p1=value1&p2=v2#frag
[routerLink]="['../../parent']" [queryParams]="{p1: 'value', p2: 'v2'}" fragment="frag"

RouterLinkでは、directives配列をインポートして使用することを忘れないでください。

import { ROUTER_DIRECTIVES } from '@angular/router';
@Component({
    directives: [ROUTER_DIRECTIVES],

命令型navigate()メソッドには開始点(つまり、relativeToパラメーター)が必要です。何も提供されていない場合、ナビゲーションは絶対的です。

import { Router, ActivatedRoute } from '@angular/router';
...
constructor(private router: Router, private route: ActivatedRoute) {}
...
this.router.navigate(["/absolute/path"]);
this.router.navigate(["../../parent"], {relativeTo: this.route});
this.router.navigate(["../sibling"],   {relativeTo: this.route});
this.router.navigate(["./child"],      {relativeTo: this.route}); // or
this.router.navigate(["child"],        {relativeTo: this.route});

// with route param     ../../parent;abc=xyz
this.router.navigate(["../../parent", {abc: 'xyz'}], {relativeTo: this.route});
// with query param and fragment   ../../parent?p1=value1&p2=v2#frag
this.router.navigate(["../../parent"], {relativeTo: this.route, 
    queryParams: {p1: 'value', p2: 'v2'}, fragment: 'frag'});

// navigate without updating the URL 
this.router.navigate(["../../parent"], {relativeTo: this.route, skipLocationChange: true});

1
このrouter.navigate(string)メソッドは、現在のバージョンのAngular(2.2)には存在しないようです。ドキュメントを検索したところ、が見つかりましたnavigate(commands: any[], extras?: NavigationExtras) : Promise<boolean>。それとも私は完全に何かが欠けていますか?
トマト

2
@Tomato、ルートの周りに[]を付ける必要があります。たとえば、this.router.navigate(["../../ parent"]、{relativeTo:this.route});
gye 2017年

2
relativeTotypescriptの代わりにhtmlで[routerLink]を使用している場合、どのようにデータを渡しますか?
redfox05 2017年

サービスも同じですか?
oCcSking

何らかの理由で、私の場合、親(から)に移動する../../../代わりに../を使用する必要があります。'/users''/users/1'
nelson6e 6520

48

これは2017年春の時点で私にとってはうまくいくようです:

goBack(): void {
  this.router.navigate(['../'], { relativeTo: this.route });
}

コンポーネントctorが受け入れActivatedRouteRouter次のようにインポートされた場合:

import { ActivatedRoute, Router } from '@angular/router';


4
日付よりも、たまたま使用しているAngularバージョンについて言及する方が便利です。
isherwood 2018年

@isherwood同意します。お詫び申し上げます。正しく覚えていれば、Angular 4.0.x用に作成しましたが、4.3.xでも機能していました。残念ながら、私は、今角度から離れて移動してきた
ne1410s

@ ne1410sありがとうございました。親戚がいませんでした:this.route
Ian Samz 2018年

注:遅延ロードされたモジュールの追加のルーターセグメントでは機能しません。例parentPath:: 'work:queue'(子があります)および子はパラメーターを使用して子モジュールをロードします。fullCurrentPath: '作業/出荷/モジュール/リスト'。上記のコードはparentPathからロードできませんfullCurrentPath
ドントーマスボイル

34

このように親ルートに移動できます

this.router.navigate(['.'], { relativeTo: this.activeRoute.parent });

コンストラクターに現在アクティブなルートを挿入する必要があります

constructor(
    private router: Router,
    private activeRoute: ActivatedRoute) {

  }

2
説明を追加すると、この回答がより便利になります。
Sagar Zala 2018年

多くの人がthis.router.navigate(["../ sibling"]、{relativeTo:this.route});で兄弟にナビゲートすることを提案しています。ただし、これはもう機能していません。私はこの答えがおそらくうまくいくと思いました。'../'を使用して親に移動する代わりに。this.route.parentへthis.routeからの変更relativeToでは、正しい方法である
テリー・ラム

1
@ChrisLamothe:そうそう私は間違いを犯した。それは一般的な場合に機能します。ただし、補助ルートでは機能しません。つまり、this.router.navigate(['../ sibling'])は機能していますが、this.router.navigate([{outlets:{'secondary':['../ sibling']}}])は機能していません。補助ルーティングでは、this.router.navigate([{outlets:{'secondary':['sibling']}}]、{relativeTo:this.activateRoute.parent})を使用する必要があります。
テリー・ラム

2
また、this.router.navigate(['.'], {relativeTo: this.activeRoute.parent});/ users / createと/ users / edit / 123の2つのパスで同じコンポーネントを使用する場合、この回答のナビゲーション方法は正しく機能します。どちらの場合も、親/ usersに移動します。の通常のナビゲーションthis.router.navigate([".."], {relativeTo: this.activeRoute})は、users / createに対してのみ機能しますが、存在しない/ users / edit / routeに移動するため、users / edit / 123に対しては機能しません。
Roganik

1
+1は代替手段ですが、個人的には、私は少しバイトチェイサーであり、親への参照を削除するために、パラメーター[".."]に余分なドットを投資します{relativeTo:this.route}
KonradViltersten19年

7
constructor(private router: Router) {}

navigateOnParent() {
  this.router.navigate(['../some-path-on-parent']);
}

ルーターはサポートします

  • 絶対パス/xxx-ルートコンポーネントのルーターで開始
  • 相対パスxxx-現在のコンポーネントのルーターで開始
  • 相対パス../xxx-現在のコンポーネントの親ルーターで開始

このコードは質問に答えることができますが、質問に答える理由方法に関する追加のコンテキストを提供すると、長期的な価値が大幅に向上します。説明を追加するには、回答を編集してください。
Toby Speight 2016年

1
@TobySpeightまあまあ。私../は十分に知られていると思いましたが、結局それはまだ曖昧です。ヒントをありがとう。
ギュンターZöchbauer

1
答えてくれてありがとう、私はかなり長い間このウェブサイトに取り組んできました、それでAngularは明らかにそれ以来更新されました。現在のバージョンでこのソリューションを試しましたが、機能しません。更新させてください。後でコメントします。
Carl Boisvert 2016年

1
コードが期待どおりに機能しません。ただし、ナビゲートする呼び出しの2番目のパラメーターとして{relativeTo:this.route}を明示的追加することにより、機能します。あなたの答えが一般的に極端な程度の正確さを持っているという事実がなかったら、私はそれを愚かなタイプミスにチョークで書きます。答えが提供されてからのルーターの動作の変化(3。6年前、Angularの年では半世紀のようなもの)でしょうか?
KonradViltersten19年

これは古い答えであり、ルーターはこの時点で大きく変更されました。賛成票が多い回答がいくつかあることを考えると、私の回答は時代遅れだと思います。私はもうそれほど多くのWebUIの作業を行っておらず、頭のてっぺんにすべての詳細がありません。
ギュンターZöchbauer

6

現在のルートまたは親ルートのパラメーターの数に関係なく、親コンポーネントに移動するには:Angular 6 update 1/21/19

   let routerLink = this._aRoute.parent.snapshot.pathFromRoot
        .map((s) => s.url)
        .reduce((a, e) => {
            //Do NOT add last path!
            if (a.length + e.length !== this._aRoute.parent.snapshot.pathFromRoot.length) {
                return a.concat(e);
            }
            return a;
        })
        .map((s) => s.path);
    this._router.navigate(routerLink);

これには、シングルトンルーターで使用できる絶対ルートであるという追加のボーナスがあります。

(確かにAngular 4+、おそらくAngular 2も。)


奇妙なことに、これは常に空の配列を返し、親ルートがルート自体でない場合に限り、親ルートに移動しthis._router.navigate([])ながら、と同じ結果を達成し this._router.navigate([[]])ます。
Ashish Jhanwar 2018

Angular 6の変更と、ルートに子を含む親と子での適切な親の検索を反映するようにコードを更新しました。
ドントーマスボイル

これはあなたのユースケースに固有のものではありませんか?最後のパスを追加しないと、['orders'、 '123'、 'items'、1]が['orders']に変わるように見えますが、これはまったく正しくないようです。いずれにせよ、Angular 5から7に移行しただけで、このコード化には触れませんでした。
kayjtea

それらは私のページのdivの数です..すべてのdivをクリックすると、クエリパラメーターを渡し、コンポーネントをロードします。今ブラウザの戻るボタンを使用して、私はそれを行う方法に戻りたいですか?
Vrajendra SinghMandloi20年

4

別の方法はこのようになる可能性があります

this._router.navigateByUrl(this._router.url.substr(0, this._router.url.lastIndexOf('/'))); // go to parent URL

これがコンストラクターです

constructor(
    private _activatedRoute: ActivatedRoute,
    private _router: Router
  ) { }

4

あまり苦労せずに:

this.router.navigate(['..'], {relativeTo: this.activeRoute, skipLocationChange: true});

パラメータ'..'は、ナビゲーションを1レベル上、つまり親にします:)


skipLocationChangeの目的/必要性について言及することをお勧めします。
KonradViltersten19年

1

私のルートには次のようなパターンがあります。

  • ユーザー/編集/ 1->編集
  • user / create / 0->作成
  • ユーザー/->リスト

たとえば、編集ページを表示していて、リストページに戻る必要がある場合は、ルート上で2レベル上に戻ります。

そのことを考えて、「level」パラメーターを使用してメソッドを作成しました。

goBack(level: number = 1) {
    let commands = '../';
    this.router.navigate([commands.repeat(level)], { relativeTo: this.route });
}

したがって、編集からリストに移動するには、次のようなメソッドを呼び出します。

this.goBack(2);

0

uiSrefディレクティブを使用している場合は、これを行うことができます

uiSref="^"

0

私の解決策は次のとおりです。

const urlSplit = this._router.url.split('/');
this._router.navigate([urlSplit.splice(0, urlSplit.length - 1).join('/')], { relativeTo: this._route.parent });

そしてRouter注射:

private readonly _router: Router

0

これのどれも私のために働きませんでした...私は使用しなければなりませんでした:

import { Router } from '@angular/router';

private router: Router

this.router.navigate([this.router.url.substring(0, this.router.url.lastIndexOf('/'))]);

これが機能する理由をいくつか説明して、回答を更新してください。回答方法をご覧ください。
GeraldZehetner20年

-2

からコンストラクターに場所を追加します @angular/common

constructor(private _location: Location) {}

back関数を追加します。

back() {
  this._location.back();
}

そしてあなたの見解では:

<button class="btn" (click)="back()">Back</button>

5
これは、以前に親ルートにいた場合にのみ機能します。親のルートは、ブラウザの履歴とは何の関係もありません...
leviathanbadger

戻るが、コンポーネントの親には移動しない
Andrew Andreev 2017

これは使用しないでください。ユーザーが外部サイトからコンポーネントにアクセスすると、そのサイトに戻されます。このコードは、ブラウザの戻るボタンをクリックするのと同じです
T04435 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.