Bagaimana cara saya menavigasi ke rute induk dari rute anak?

94

Masalah saya cukup klasik. Saya memiliki bagian pribadi dari aplikasi yang berada di belakang file login form. Ketika login berhasil, ia pergi ke rute anak untuk aplikasi admin.

Masalah saya adalah bahwa saya tidak dapat menggunakan global navigation menukarena router mencoba untuk merutekan saya AdminComponentalih - alih milik saya AppCompoment. Jadi navigasi saya rusak.

Masalah lainnya adalah jika seseorang ingin mengakses URL secara langsung, saya ingin mengarahkan ke rute "login" orang tua. Tapi aku tidak bisa membuatnya berhasil. Bagi saya sepertinya dua masalah ini serupa.

Tahu bagaimana itu bisa dilakukan?

Carl Boisvert
sumber
3
tolong tambahkan beberapa kode
Jiang YD

Jawaban:

157

Apakah Anda menginginkan tautan / HTML atau Anda ingin merutekan secara imperatif / dalam kode?

Tautan : Direktif RouterLink selalu memperlakukan tautan yang disediakan sebagai delta ke URL saat ini:

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

Dengan RouterLink, ingatlah untuk mengimpor dan menggunakan directivesarray:

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

Imperatif : navigate()Metode ini membutuhkan titik awal (yaitu, relativeToparameter). Jika tidak ada yang tersedia, navigasi mutlak:

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});
Mark Rajcok
sumber
1
yang router.navigate(string)metode tampaknya tidak ada dalam versi saat ini dari sudut (2,2). Saya mencari di dokumen dan hanya menemukan navigate(commands: any[], extras?: NavigationExtras) : Promise<boolean>. Atau apakah saya benar-benar melewatkan sesuatu?
Tomat
2
@Tomat, Anda harus meletakkan [] di sekitar rute. Misalnya, this.router.navigate (["../../ parent"], {relativeTo: this.route});
gye
2
bagaimana Anda melewatkan relativeTodata saat Anda menggunakan [routerLink] di html alih-alih skrip ketikan?
redfox05
sama dengan layanan?
oCcSking
Untuk beberapa alasan, dalam kasus saya, saya harus menggunakan ../../../daripada ../menavigasi ke orang tua ( '/users'dari '/users/1').
nelson6e65
49

Ini sepertinya berhasil untuk saya pada Musim Semi 2017:

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

Di mana ctor komponen Anda menerima ActivatedRoutedan Router, diimpor sebagai berikut:

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

ne1410s
sumber
4
Daripada tanggal, akan lebih berguna untuk menyebutkan versi Angular yang kebetulan Anda gunakan.
isherwood
@isherwood Saya setuju. Permintaan maaf. Jika saya ingat dengan benar, saya menulisnya untuk Angular 4.0.x dan masih berfungsi di 4.3.x. Sayangnya saya telah pindah dari Angular sekarang,
ne1410s
@ ne1410s Terima kasih banyak yang merindukan kerabat: this.route
Ian Samz
Catatan: TIDAK akan berfungsi dengan segmen router tambahan pada modul yang dimuat lambat. EX:: parentPath'work: queue' (yang memiliki anak) dan kata anak memuat modul anak dengan parameter. fullCurrentPath: 'pekerjaan / pengiriman / modul / daftar'. Kode di atas tidak dapat dimuat parentPathdari fullCurrentPath.
Don Thomas Boyle
34

Anda dapat menavigasi ke root induk Anda seperti ini

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

Anda perlu memasukkan Route aktif saat ini ke dalam konstruktor

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

  }
Chris Lamothe
sumber
2
Menambahkan beberapa penjelasan akan membuat jawaban ini lebih berguna.
Sagar Zala
Banyak orang menyarankan navigasi ke saudara dengan this.router.navigate (["../ sibling"], {relativeTo: this.route}); Namun, ini tidak berfungsi lagi. Saya menemukan jawaban ini mungkin berhasil. Alih-alih menggunakan '../' untuk menavigasi ke induk. mengubah relativeTo dari this.route to this.route.parent adalah cara yang benar
Terry Lam
1
@ChrisLamothe: Oh ya, saya melakukan kesalahan. Ini bekerja dalam kasus umum. Namun, itu tidak berfungsi di rute tambahan. Artinya this.router.navigate (['../ sibling']) sedang bekerja tetapi tidak this.router.navigate ([{outlet: {'secondary': ['../sibling']}}]). Dalam perutean tambahan, saya harus menggunakan this.router.navigate ([{outlet: {'secondary': ['sibling']}}], {relativeTo: this.activatedRoute.parent}).
Terry Lam
2
Selain itu, metode navigasi dari jawaban ini this.router.navigate(['.'], {relativeTo: this.activeRoute.parent});akan berfungsi dengan benar dalam kasus, ketika Anda menggunakan komponen yang sama di dua jalur: / users / create dan / users / edit / 123. Dalam kedua kasus, ini akan mengarah ke orang tua / pengguna. Navigasi biasa dengan this.router.navigate([".."], {relativeTo: this.activeRoute})hanya akan berfungsi untuk pengguna / buat tetapi tidak akan berfungsi untuk pengguna / edit / 123 karena akan menavigasi ke / pengguna / edit / rute yang tidak ada.
Roganik
1
+1 untuk alternatif tetapi secara pribadi, saya sedikit pengejar byte dan akan menginvestasikan titik ekstra di parameter, [".."] , untuk menghilangkan referensi ke induk, {relativeTo: this.route} .
Konrad Viltersten
7
constructor(private router: Router) {}

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

Router mendukung

  • jalur absolut /xxx- dimulai pada router dari komponen root
  • jalur relatif xxx- dimulai pada router dari komponen saat ini
  • jalur relatif ../xxx- dimulai pada router induk dari komponen saat ini
Günter Zöchbauer
sumber
Meskipun kode ini dapat menjawab pertanyaan, memberikan konteks tambahan tentang mengapa dan / atau bagaimana kode ini menjawab pertanyaan akan secara signifikan meningkatkan nilai jangka panjangnya. Harap edit jawaban Anda untuk menambahkan penjelasan.
Toby Speight
1
@Toby Cukup adil. Saya berasumsi ../sudah cukup dikenal, tapi pada akhirnya masih ambigu. Terima kasih atas petunjuknya.
Günter Zöchbauer
1
Terima kasih atas jawabannya, saya telah mengerjakan situs web ini selama beberapa waktu, jadi Angular jelas telah diperbarui sejak itu. Saya telah mencoba solusi ini dalam versi saya saat ini dan tidak berhasil. Biarkan saya memperbarui dan saya akan berkomentar kembali setelahnya.
Carl Boisvert
1
Saya tidak mendapatkan kode Anda berfungsi seperti yang diharapkan. Namun, dengan menambahkan secara eksplisit , {relativeTo: this.route} sebagai parameter kedua dalam panggilan untuk menavigasi , ini berhasil. Saya akan menganggapnya sebagai kesalahan ketik yang bodoh jika bukan karena fakta bahwa jawaban Anda umumnya memiliki tingkat akurasi yang ekstrem. Apakah mungkin perubahan perilaku router sejak jawaban diberikan (3,6 tahun yang lalu, yang dalam tahun Angular seperti keabadian setengah)?
Konrad Viltersten
Ini adalah jawaban lama dan router banyak berubah saat ini. Saya rasa jawaban saya sudah ketinggalan zaman mengingat ada beberapa jawaban dengan lebih banyak upvote. Saya tidak melakukan banyak hal UI web lagi dan tidak memiliki semua detail di atas kepala saya.
Günter Zöchbauer
6

Untuk menavigasi ke komponen induk terlepas dari jumlah parameter di rute saat ini atau rute induk: 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);

Ini memiliki bonus tambahan sebagai rute absolut yang dapat Anda gunakan dengan Router tunggal.

(Angular 4+ pasti, mungkin Angular 2 juga.)

kayjtea
sumber
anehnya, ini selalu mengembalikan larik kosong, dan mencapai hasil yang sama seperti this._router.navigate([]), sementara this._router.navigate([[]])mengambil ke rute induk, jika dan hanya jika rute induk bukan root itu sendiri.
Ashish Jhanwar
kode yang diperbarui untuk mencerminkan perubahan Angular 6 dan temuan induk yang tepat dengan induk dan anak yang berisi anak dalam rute.
Don Thomas Boyle
Apakah Anda yakin ini bukan sesuatu yang spesifik untuk kasus penggunaan Anda? Tampaknya tidak menambahkan jalur terakhir akan mengubah ['pesanan', '123', 'item', 1] menjadi hanya ['pesanan'], yang tampaknya tidak benar sama sekali. Bagaimanapun, kami baru saja beralih dari Angular 5 ke 7 dan tidak menyentuh kode ini.
kayjtea
mereka adalah jumlah div di halaman saya .. pada klik setiap div saya melewati parms query dan memuat sebuah komponen. sekarang menggunakan tombol kembali browser saya ingin kembali bagaimana melakukan itu?
Vrajendra Singh Mandloi
4

Cara lain bisa seperti ini

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

dan inilah konstruktornya

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

tanpa banyak basa-basi:

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

parameter '..' membuat navigasi satu tingkat ke atas, yaitu induk :)

Igor Zinin
sumber
Anda mungkin ingin menyebutkan tujuan / kebutuhan skipLocationChange .
Konrad Viltersten
1

Rute saya memiliki pola seperti ini:

  • pengguna / edit / 1 -> Edit
  • pengguna / buat / 0 -> Buat
  • pengguna / -> Daftar

Ketika saya berada di halaman Edit, misalnya, dan saya perlu kembali ke halaman daftar, saya akan mengembalikan 2 level ke atas pada rute.

Berpikir tentang itu, saya membuat metode saya dengan parameter "level".

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

Jadi, untuk beralih dari edit ke daftar saya memanggil metode seperti itu:

this.goBack(2);
Carlinhos
sumber
0

Jika Anda menggunakan arahan uiSref maka Anda dapat melakukan ini

uiSref="^"
Zuriel
sumber
0

Solusi saya adalah:

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

Dan Routerinjeksi:

private readonly _router: Router
anlijudavid.dll
sumber
0

Semua ini tidak berhasil untuk saya ... Saya harus menggunakan:

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

private router: Router

this.router.navigate([this.router.url.substring(0, this.router.url.lastIndexOf('/'))]);
Dimitri Dedusse Odyssound
sumber
Harap perbarui jawaban Anda dengan penjelasan mengapa ini berhasil. Silakan lihat Bagaimana Menjawab .
Gerald Zehetner
-2

tambahkan Lokasi ke konstruktor Anda dari @angular/common

constructor(private _location: Location) {}

tambahkan fungsi kembali:

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

lalu dalam pandangan Anda:

<button class="btn" (click)="back()">Back</button>
pengguna3021615
sumber
5
Ini hanya berfungsi jika Anda sebelumnya berada di rute induk. Rute induk tidak ada hubungannya dengan riwayat browser ...
leviathanbadger
itu menavigasi kembali, tetapi tidak menavigasi ke induk komponen
Andrew Andreev
Ini tidak boleh digunakan, jika pengguna pergi ke komponen dari situs eksternal, itu akan dibawa kembali ke situs itu. Kode ini sama dengan mengklik TOMBOL KEMBALI DI BROWSER
T04435