ฉันจะนำทางไปยังเส้นทางหลักจากเส้นทางลูกได้อย่างไร


94

ปัญหาของฉันค่อนข้างคลาสสิก ฉันมีส่วนส่วนตัวของแอปพลิเคชันซึ่งอยู่เบื้องหลังไฟล์login form. เมื่อการเข้าสู่ระบบสำเร็จระบบจะไปยังเส้นทางลูกสำหรับแอปพลิเคชันผู้ดูแลระบบ

ปัญหาของฉันคือฉันไม่สามารถใช้งานได้global navigation menuเนื่องจากเราเตอร์พยายามกำหนดเส้นทางในฉันAdminComponentแทนที่จะเป็นAppCompomentไฟล์. ดังนั้นการนำทางของฉันเสีย

ปัญหาอีกประการหนึ่งคือหากมีผู้ต้องการเข้าถึง URL โดยตรงฉันต้องการเปลี่ยนเส้นทางไปยังเส้นทาง "เข้าสู่ระบบ" หลัก แต่ฉันไม่สามารถทำให้มันทำงานได้ สำหรับฉันแล้วดูเหมือนว่าสองประเด็นนี้จะคล้ายกัน

มีความคิดว่าจะทำได้อย่างไร?


3
โปรดเพิ่มรหัส
Jiang YD

คำตอบ:


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)วิธีการไม่ได้ดูเหมือนจะมีอยู่ในรุ่นปัจจุบันของเชิงมุม (2.2) ฉันค้นหาในเอกสารnavigate(commands: any[], extras?: NavigationExtras) : Promise<boolean>และพบเพียง หรือฉันพลาดอะไรไปโดยสิ้นเชิง?
มะเขือเทศ

2
@ มะเขือเทศคุณต้องใส่ [] รอบ ๆ เส้นทาง ตัวอย่างเช่น this.router.navigate (["../../ parent"], {relativeTo: this.route});
gye

2
คุณส่งrelativeToข้อมูลอย่างไรเมื่อคุณใช้ [routerLink] ใน html แทน typescript
redfox05

เหมือนกันกับบริการ?
oCcSking

ด้วยเหตุผลบางประการในกรณีของฉันฉันต้องใช้../../../แทน../เพื่อนำทางไปยังผู้ปกครอง ( '/users'จาก'/users/1')
nelson6e65

49

ดูเหมือนว่าจะใช้ได้ผลสำหรับฉันในฤดูใบไม้ผลิปี 2017

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

โดยที่ ctor คอมโพเนนต์ของคุณยอมรับActivatedRouteและRouterนำเข้าดังนี้:

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


4
แทนที่จะเป็นวันที่จะมีประโยชน์มากกว่าที่จะพูดถึงเวอร์ชัน Angular ที่คุณใช้อยู่
isherwood

@isherwood ฉันเห็นด้วย ขอโทษ. ถ้าฉันจำไม่ผิดฉันเขียนมันสำหรับ Angular 4.0.x และมันยังใช้งานได้ใน 4.3.x. น่าเสียดายที่ฉันได้ย้ายออกจาก Angular แล้ว
ne1410s

@ ne1410s ขอบคุณมากที่ขาดญาติ: this.route
Ian Samz

หมายเหตุ: จะไม่ทำงานกับเซ็กเมนต์เราเตอร์เพิ่มเติมในโมดูลที่โหลดแบบขี้เกียจ EX:: parentPath'work: que' (ซึ่งมีลูก) และกล่าวว่าเด็ก ๆ โหลดโมดูลลูกด้วยพารามิเตอร์ fullCurrentPath: 'งาน / การจัดส่ง / โมดูล / รายการ' รหัสข้างต้นไม่สามารถโหลดจากparentPath fullCurrentPath
Don Thomas Boyle

34

คุณสามารถไปที่รูทหลักของคุณได้เช่นนี้

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

คุณจะต้องฉีดเส้นทางที่ใช้งานปัจจุบันในตัวสร้าง

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

  }

2
การเพิ่มคำอธิบายจะทำให้คำตอบนี้มีประโยชน์มากขึ้น
Sagar Zala

หลายคนแนะนำให้ไปที่ sibling โดย this.router.navigate (["../ sibling"], {relativeTo: this.route}); อย่างไรก็ตามนี่ใช้งานไม่ได้อีกต่อไป ฉันพบว่าคำตอบนี้อาจทำงานได้ แทนที่จะใช้ "../" เพื่อนำทางไปยังพาเรนต์ เปลี่ยน relativeTo จาก this.route เป็น this.route.parent เป็นวิธีที่ถูกต้อง
Terry Lam

1
@ChrisLamothe: โอ้ใช่ฉันทำผิดพลาด ใช้งานได้ในกรณีทั่วไป อย่างไรก็ตามมันไม่ทำงานในเส้นทางเสริม นั่นหมายความว่า this.router.navigate (['../ sibling']) กำลังทำงาน แต่ไม่ใช่ this.router.navigate ([{ร้าน: {'รอง': ['../sibling']}}]) ในการกำหนดเส้นทางเสริมฉันต้องใช้ this.router.navigate ([{ร้านค้า: {'secondary': ['sibling']}}], {relativeTo: this.activatedRoute.parent})
Terry Lam

2
นอกจากนี้วิธีการนำทางจากคำตอบนี้this.router.navigate(['.'], {relativeTo: this.activeRoute.parent});จะทำงานได้อย่างถูกต้องในบางกรณีเมื่อคุณใช้ส่วนประกอบเดียวกันในสองเส้นทาง: / users / create และ / users / edit / 123 ในทั้งสองกรณีจะนำทางไปยังผู้ปกครอง / ผู้ใช้ การนำทางปกติด้วยthis.router.navigate([".."], {relativeTo: this.activeRoute})จะใช้ได้เฉพาะกับผู้ใช้ / สร้าง แต่จะใช้ไม่ได้กับผู้ใช้ / แก้ไข / 123 เนื่องจากจะนำทางไปยัง / users / edit / route ที่ไม่มีอยู่
Roganik

1
+1 สำหรับทางเลือก แต่ส่วนตัวผมบิตของนายพรานไบต์และจะลงทุนเพิ่มจุดเสริมในพารามิเตอร์[ ".."]เพื่อขจัดอ้างอิงถึงผู้ปกครอง{relativeTo: this.route}
Konrad Viltersten

7
constructor(private router: Router) {}

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

เราเตอร์รองรับ

  • เส้นทางที่แน่นอน/xxx- เริ่มต้นที่เราเตอร์ขององค์ประกอบราก
  • เส้นทางสัมพัทธ์xxx- เริ่มต้นบนเราเตอร์ของส่วนประกอบปัจจุบัน
  • เส้นทางสัมพัทธ์../xxx- เริ่มต้นบนเราเตอร์หลักของส่วนประกอบปัจจุบัน

แม้ว่ารหัสนี้อาจตอบคำถามได้ แต่การให้บริบทเพิ่มเติมเกี่ยวกับสาเหตุและ / หรือวิธีการตอบคำถามจะช่วยเพิ่มมูลค่าในระยะยาวได้อย่างมาก โปรดแก้ไขคำตอบของคุณเพื่อเพิ่มคำอธิบาย
Toby Speight

1
@TobySpeight พอใช้. ฉันคิดว่า../เป็นที่รู้จักกันดีพอสมควร แต่สุดท้ายก็ยังคลุมเครือ ขอบคุณสำหรับคำแนะนำ
GünterZöchbauer

1
ขอบคุณสำหรับคำตอบฉันทำงานบนเว็บไซต์นี้มาระยะหนึ่งแล้วดังนั้น Angular จึงได้รับการอัปเดตอย่างชัดเจนตั้งแต่นั้นมา ฉันได้ลองใช้โซลูชันนี้ในเวอร์ชันปัจจุบันแล้ว แต่ไม่ได้ผล ให้ฉันอัปเดตและฉันจะแสดงความคิดเห็นในภายหลัง
Carl Boisvert

1
ฉันไม่ได้รับรหัสของคุณทำงานตามที่คาดไว้ อย่างไรก็ตามการเพิ่ม{relativeTo: this.route}อย่างชัดเจนเป็นพารามิเตอร์ที่สองในการเรียกเพื่อนำทางก็จะทำงานได้ ฉันจะชอล์คเป็นการพิมพ์ผิดโง่ ๆ หากไม่ได้เป็นเพราะความจริงที่ว่าคำตอบของคุณโดยทั่วไปมีความแม่นยำสูง อาจเป็นการเปลี่ยนแปลงพฤติกรรมของเราเตอร์ตั้งแต่มีการให้คำตอบ (3.6 ปีที่แล้วซึ่งในปีเชิงมุมเปรียบเสมือนชั่วนิรันดร์ครึ่งหนึ่ง)
Konrad Viltersten

นี่เป็นคำตอบเก่าและเราเตอร์เปลี่ยนไปมากในเวลานี้ ฉันคิดว่าคำตอบของฉันล้าสมัยไปแล้วเนื่องจากมีคำตอบหลายคำตอบที่มีการโหวตมากขึ้น ฉันไม่ได้ทำเว็บ UI มากขนาดนั้นอีกต่อไปและไม่มีรายละเอียดทั้งหมดที่ด้านบนของหัว
GünterZöchbauer

6

เพื่อนำทางไปยังองค์ประกอบหลักโดยไม่คำนึงถึงจำนวนพารามิเตอร์ในเส้นทางปัจจุบันหรือเส้นทางหลัก: อัปเดต Angular 6 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

อัปเดตโค้ดเพื่อแสดงการเปลี่ยนแปลง Angular 6 และการค้นหาผู้ปกครองที่เหมาะสมกับผู้ปกครองและเด็กที่มีลูกในเส้นทาง
Don Thomas Boyle

แน่ใจหรือว่านี่ไม่ใช่สิ่งที่เฉพาะเจาะจงสำหรับกรณีการใช้งานของคุณ ดูเหมือนว่าการไม่ต่อท้ายเส้นทางสุดท้ายจะทำให้ ['orders', '123', 'items', 1] เป็นเพียง ['orders'] ซึ่งดูเหมือนจะไม่ถูกต้องเลย ไม่ว่าในกรณีใดเราเพิ่งเปลี่ยนจาก Angular 5 เป็น 7 และไม่ได้แตะรหัสนี้
kayjtea

พวกเขาคือจำนวน div ในหน้าของฉัน .. เมื่อคลิกทุก div ฉันผ่าน parms แบบสอบถามและโหลดส่วนประกอบ ตอนนี้ใช้ปุ่มย้อนกลับของเบราว์เซอร์ฉันต้องการย้อนกลับต้องทำอย่างไร
Vrajendra Singh Mandloi

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});

พารามิเตอร์".. "ทำให้การนำทางขึ้นหนึ่งระดับเช่น parent :)


คุณอาจต้องการที่จะกล่าวถึงวัตถุประสงค์ / ความต้องการของskipLocationChange
Konrad Viltersten

1

เส้นทางของฉันมีรูปแบบดังนี้:

  • ผู้ใช้ / แก้ไข / 1 -> แก้ไข
  • ผู้ใช้ / create / 0 -> สร้าง
  • ผู้ใช้ / -> รายการ

ตัวอย่างเช่นเมื่อฉันอยู่ในหน้าแก้ไขและฉันต้องการกลับไปที่หน้ารายการฉันจะส่งคืน 2 ระดับขึ้นไปบนเส้นทาง

เมื่อคิดอย่างนั้นฉันจึงสร้างเมธอดของฉันด้วยพารามิเตอร์ "ระดับ"

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

ดังนั้นในการเปลี่ยนจากแก้ไขไปยังรายการฉันเรียกวิธีการเช่นนั้น:

this.goBack(2);


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('/'))]);

โปรดอัปเดตคำตอบของคุณด้วยคำอธิบายว่าเหตุใดจึงได้ผล โปรดดูวิธีการคำตอบ
Gerald Zehetner

-2

เพิ่มตำแหน่งให้กับตัวสร้างของคุณจาก @angular/common

constructor(private _location: Location) {}

เพิ่มฟังก์ชันด้านหลัง:

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

แล้วในมุมมองของคุณ:

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

5
วิธีนี้ใช้ได้เฉพาะเมื่อคุณอยู่ในเส้นทางหลักก่อนหน้านี้ เส้นทางผู้ปกครองไม่มีส่วนเกี่ยวข้องกับประวัติเบราว์เซอร์ ...
leviathanbadger

มันนำทางย้อนกลับ แต่ไม่นำทางไปยังพาเรนต์ขององค์ประกอบ
Andrew Andreev

ไม่ควรใช้สิ่งนี้หากผู้ใช้ไปที่คอมโพเนนต์จากไซต์ภายนอกระบบจะนำกลับไปที่ไซต์นั้น รหัสนี้เหมือนกับการคลิกปุ่มย้อนกลับในเบราว์เซอร์
T04435
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.