Làm cách nào để điều hướng đến tuyến đường mẹ từ tuyến đường con?


90

Vấn đề của tôi là khá cổ điển. Tôi có một phần riêng tư của một ứng dụng đằng sau a login form. Khi đăng nhập thành công, nó sẽ chuyển đến một tuyến con cho ứng dụng quản trị.

Vấn đề của tôi là tôi không thể sử dụng global navigation menuvì bộ định tuyến cố gắng định tuyến trong của tôi AdminComponentthay vì của tôi AppCompoment. Vì vậy, điều hướng của tôi bị hỏng.

Một vấn đề khác là nếu ai đó muốn truy cập trực tiếp vào URL, tôi muốn chuyển hướng đến tuyến đường "đăng nhập" chính. Nhưng tôi không thể làm cho nó hoạt động. Đối với tôi, có vẻ như hai vấn đề này tương tự nhau.

Bất kỳ ý tưởng làm thế nào nó có thể được thực hiện?


3
vui lòng thêm một số mã
Jiang YD

Câu trả lời:


154

Bạn muốn một liên kết / HTML hay bạn muốn định tuyến theo thứ bậc / trong mã?

Liên kết : Lệnh RouterLink luôn coi liên kết được cung cấp như một dấu tam giác với URL hiện tại:

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

Với RouterLink, hãy nhớ nhập và sử dụng directivesmảng:

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

Imperative : navigate()Phương thức yêu cầu một điểm bắt đầu (tức là relativeTotham số). Nếu không có gì được cung cấp, điều hướng là tuyệt đối:

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
các router.navigate(string)phương pháp dường như không tồn tại trong phiên bản hiện tại của góc (2.2). Tôi đã tìm kiếm trong tài liệu và chỉ tìm thấy navigate(commands: any[], extras?: NavigationExtras) : Promise<boolean>. Hay tôi hoàn toàn thiếu thứ gì đó?
Tomato

2
@Tomato, bạn cần đặt [] xung quanh các tuyến đường. Ví dụ: this.router.navigate (["../../ parent"], {relativeTo: this.route});
gye

2
làm cách nào để chuyển relativeTodữ liệu khi bạn đang sử dụng [routerLink] trong html thay vì typecript?
redfox05

cùng với các dịch vụ?
oCcSking

Vì một số lý do, trong trường hợp của tôi, tôi phải sử dụng ../../../thay vì ../để điều hướng đến phụ huynh ( '/users'từ '/users/1').
nelson6e65

47

Điều này dường như hiệu quả đối với tôi kể từ mùa Xuân 2017:

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

Nơi ctor thành phần của bạn chấp nhận ActivatedRouteRouter, được nhập như sau:

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


4
Thay vì một ngày, sẽ hữu ích hơn nếu đề cập đến phiên bản Angular mà bạn đang sử dụng.
isherwood

@isherwood Tôi đồng ý. Xin lỗi. Nếu tôi nhớ không lầm, tôi đã viết nó cho Angular 4.0.x và nó vẫn hoạt động trong 4.3.x. Thật không may, tôi đã rời khỏi Angular ngay bây giờ,
ne1410s

@ ne1410s Cảm ơn rất nhiều đã bỏ lỡ tương đối: this.route
Ian Samz

Lưu ý: Sẽ KHÔNG hoạt động với các phân đoạn bộ định tuyến bổ sung trên các mô-đun được tải chậm. EX:: parentPath'work: queue' (có trẻ em) và cho biết trẻ em tải mô-đun con với các tham số. fullCurrentPath: 'công việc / vận chuyển / mô-đun / danh sách'. Mã trên không thể tải parentPathtừ fullCurrentPath.
Don Thomas Boyle

32

Bạn có thể điều hướng đến thư mục gốc của bạn như thế này

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

Bạn sẽ cần phải đưa Tuyến đang hoạt động hiện tại vào hàm tạo

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

  }

2
Thêm một số giải thích sẽ làm cho câu trả lời này hữu ích hơn.
Sagar Zala

Nhiều người đề xuất điều hướng đến anh chị em bằng this.router.navigate (["../ anh / chị / em"], {relativeTo: this.route}); Tuy nhiên, điều này không hoạt động nữa. Tôi thấy câu trả lời này có thể hoạt động. Thay vì sử dụng '../' để điều hướng đến cha mẹ. thay đổi relativeTo từ this.route để this.route.parent là cách chính xác
Terry Lâm

1
@ChrisLamothe: Ồ vâng, tôi đã nhầm lẫn. Nó hoạt động trong trường hợp chung. Tuy nhiên, nó không hoạt động trong các tuyến phụ trợ. Điều đó có nghĩa là this.router.navigate (['../ anh / chị / em']) đang hoạt động nhưng không phải this.router.navigate ([{outlets: {'Secondary': ['../sibling']}}]). Trong định tuyến bổ trợ, tôi phải sử dụng this.router.navigate ([{outlets: {'Secondary': ['anh chị em']}}], {relativeTo: this.actiisedRoute.parent}).
Terry Lam

2
Ngoài ra, phương pháp điều hướng từ câu trả lời this.router.navigate(['.'], {relativeTo: this.activeRoute.parent});này sẽ hoạt động chính xác trong một trường hợp, khi bạn sử dụng cùng một thành phần trong hai đường dẫn: / users / create và / users / edit / 123. Trong cả hai trường hợp, nó sẽ điều hướng đến phụ huynh / người dùng. Điều hướng thông thường với this.router.navigate([".."], {relativeTo: this.activeRoute})sẽ chỉ hoạt động cho người dùng / tạo nhưng sẽ không hoạt động cho người dùng / chỉnh sửa / 123 vì nó sẽ điều hướng đến không tồn tại / người dùng / chỉnh sửa / tuyến đường.
Roganik

1
+1 cho một lựa chọn thay thế nhưng về mặt cá nhân, tôi hơi mê theo dõi byte và sẽ đầu tư thêm một dấu chấm vào tham số, [".."] , để loại bỏ tham chiếu đến cấp độ gốc, {relativeTo: this.route} .
Konrad Viltersten

7
constructor(private router: Router) {}

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

Bộ định tuyến hỗ trợ

  • đường dẫn tuyệt đối /xxx- bắt đầu trên bộ định tuyến của thành phần gốc
  • đường dẫn tương đối xxx- bắt đầu trên bộ định tuyến của thành phần hiện tại
  • đường dẫn tương đối ../xxx- bắt đầu trên bộ định tuyến mẹ của thành phần hiện tại

Mặc dù mã này có thể trả lời câu hỏi, nhưng việc cung cấp thêm ngữ cảnh liên quan đến lý do và / hoặc cách nó trả lời câu hỏi sẽ cải thiện đáng kể giá trị lâu dài của nó. Vui lòng chỉnh sửa câu trả lời của bạn để thêm một số giải thích.
Toby Speight

1
@TobySpeight Đủ công bằng. Tôi cho rằng đã ../đủ biết, nhưng cuối cùng thì nó vẫn còn mơ hồ. Cảm ơn vì gợi ý.
Günter Zöchbauer

1
Cảm ơn câu trả lời, tôi đã làm việc trên trang web này khá lâu, vì vậy Angular rõ ràng là đã được cập nhật kể từ đó. Tôi đã thử giải pháp này trong phiên bản hiện tại của mình và nó không hoạt động. Hãy để tôi cập nhật và tôi sẽ bình luận lại sau.
Carl Boisvert

1
Tôi không làm cho mã của bạn hoạt động như mong đợi. Tuy nhiên, bằng cách thêm một cách rõ ràng , {relativeTo: this.route} làm tham số thứ hai trong lệnh gọi điều hướng , nó sẽ hoạt động. Tôi sẽ đánh dấu nó đến một lỗi đánh máy ngu ngốc nếu nó không phải vì thực tế là các câu trả lời của bạn thường có mức độ chính xác cao. Có lẽ đó là một sự thay đổi trong hành vi của bộ định tuyến kể từ khi câu trả lời được cung cấp (3,6 năm trước, trong những năm Angular giống như một nửa vĩnh cửu)?
Konrad Viltersten

Đây là một câu trả lời cũ và bộ định tuyến đã thay đổi rất nhiều vào thời điểm này. Tôi nghĩ rằng câu trả lời của tôi đã lỗi thời khi xem xét rằng có một số câu trả lời có nhiều lượt ủng hộ hơn. Tôi không làm nhiều thứ như vậy về giao diện người dùng web nữa và không có tất cả thông tin chi tiết trên đầu.
Günter Zöchbauer

6

Để điều hướng đến thành phần chính bất kể số lượng tham số trong tuyến hiện tại hay tuyến mẹ: 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);

Điều này có lợi ích bổ sung là trở thành một tuyến đường tuyệt đối mà bạn có thể sử dụng với Bộ định tuyến singleton.

(Chắc chắn là Angular 4+, có thể là Angular 2 nữa.)


kỳ lạ là, điều này luôn trả về một mảng trống và đạt được kết quả giống như this._router.navigate([]), trong khi this._router.navigate([[]])đưa đến tuyến mẹ, nếu và chỉ khi tuyến mẹ không phải là chính nó.
Ashish Jhanwar

đã cập nhật mã để phản ánh những thay đổi của Angular 6 và tìm kiếm cha mẹ thích hợp với cha mẹ và con chứa con trong các tuyến.
Don Thomas Boyle

Bạn có chắc đây không phải là thứ cụ thể cho trường hợp sử dụng của bạn? Dường như không nối với đường dẫn cuối cùng sẽ biến ['đơn đặt hàng', '123', 'mục', 1] chỉ thành ['đơn đặt hàng'], điều này có vẻ không đúng chút nào. Trong mọi trường hợp, chúng tôi chỉ đi từ Angular 5 đến 7 và không chạm vào mã này.
kayjtea

chúng là số div trên trang của tôi .. khi nhấp vào mỗi div, tôi chuyển các parms truy vấn và tải một thành phần. bây giờ sử dụng nút quay lại của trình duyệt tôi muốn quay lại làm thế nào để làm điều đó?
Vrajendra Singh Mandloi

4

Một cách khác có thể như thế này

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

và đây là hàm tạo

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

3

mà không có nhiều ado:

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

tham số '..' làm cho điều hướng lên một cấp, tức là cha mẹ :)


Bạn có thể muốn đề cập đến mục đích / nhu cầu của bỏ quaLocationChange .
Konrad Viltersten

1

Các tuyến đường của tôi có dạng như sau:

  • user / edit / 1 -> Edit
  • user / create / 0 -> Create
  • người dùng / -> Danh sách

Ví dụ: khi tôi đang ở trang Chỉnh sửa và tôi cần quay lại trang danh sách, tôi sẽ quay lại 2 cấp trên lộ trình.

Suy nghĩ về điều đó, tôi đã tạo phương thức của mình với tham số "level".

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

Vì vậy, để đi từ chỉnh sửa đến danh sách, tôi gọi phương thức như vậy:

this.goBack(2);

0

thêm Vị trí vào phương thức khởi tạo của bạn từ @angular/common

constructor(private _location: Location) {}

thêm chức năng quay lại:

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

và sau đó theo quan điểm của bạn:

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

5
Điều này chỉ hoạt động nếu bạn đã ở trong tuyến mẹ trước đó. Tuyến đường cha mẹ không có gì để làm với lịch sử trình duyệt ...
leviathanbadger

nó điều hướng trở lại, nhưng không tìm đến mẹ của thành phần
Andrew Andreev

Điều này không nên được sử dụng, nếu người dùng truy cập thành phần từ một trang web bên ngoài, nó sẽ được đưa trở lại trang web đó. Mã này cũng giống như cách nhấn vào nút quay lại trong trình duyệt
T04435

0

Nếu bạn đang sử dụng chỉ thị uiSref thì bạn có thể làm điều này

uiSref="^"

0

Giải pháp của tôi là:

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

Routertiêm:

private readonly _router: Router
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.