하위 경로에서 상위 경로로 어떻게 이동합니까?


89

내 문제는 아주 고전적입니다. 나는 뒤에있는 응용 프로그램의 비공개 부분이 login form있습니다. 로그인이 성공하면 관리 응용 프로그램의 하위 경로로 이동합니다.

내 문제는 global navigation menu라우터가 내 AdminComponent.NET 대신 내 라우팅을 시도하기 때문에을 사용할 수 없다는 것입니다 AppCompoment. 그래서 내 탐색이 깨졌습니다.

또 다른 문제는 누군가 URL에 직접 액세스하려는 경우 상위 "로그인"경로로 리디렉션하고 싶다는 것입니다. 그러나 나는 그것을 작동시킬 수 없습니다. 이 두 가지 문제가 비슷한 것 같습니다.

어떻게 할 수 있는지 아십니까?


3
코드를 추가하세요
Jiang YD

답변:


153

링크 / HTML을 원하시나요? 아니면 명령 적 / 코드로 라우팅 하시겠습니까?

Link : 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>. 아니면 내가 뭔가를 완전히 놓치고 있습니까?
Tomato

2
@Tomato, 경로 주위에 []를 넣어야합니다. 예를 들면 this.router.navigate ([ "../../ parent"], {relativeTo : this.route});
gye

2
relativeTotypescript 대신 html에서 [routerLink]를 사용할 때 데이터를 어떻게 전달 합니까?
redfox05

서비스와 동일합니까?
oCcSking

어떤 이유로 든, 제 경우에는 부모 ( from ) 로 이동 하는 ../../../대신 사용해야 합니다 . ../'/users''/users/1'
nelson6e65

47

이것은 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에서도 여전히 작동합니다. 불행하게도 지금 각도에서 멀리 이동 한
ne1410s

this.route : @ ne1410s 덕분에 많이 상대 실종됐다
이안 Samz

참고 : 지연로드 된 모듈의 추가 라우터 세그먼트에서는 작동하지 않습니다. EX : parentPath: 'work : queue'(하위가 있음) 및 해당 children은 매개 변수가있는 하위 모듈을로드합니다. fullCurrentPath: '작업 / 배송 / 모듈 / 목록'. 위의 코드는로드 할 수 없습니다 parentPath에서 fullCurrentPath.
Don Thomas Boyle

32

다음과 같이 부모 루트로 이동할 수 있습니다.

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

생성자에 현재 활성 경로를 삽입해야합니다.

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

  }

2
설명을 추가하면이 답변이 더 유용 해집니다.
Sagar Zala

많은 사람들이 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.activatedRoute.parent})를 사용해야합니다.
Terry Lam

2
또한이 답변의 탐색 방법은 this.router.navigate(['.'], {relativeTo: this.activeRoute.parent});/ users / create 및 / users / edit / 123의 두 경로에서 동일한 구성 요소를 사용하는 경우 올바르게 작동합니다. 두 경우 모두 상위 / users로 이동합니다. 일반 탐색 this.router.navigate([".."], {relativeTo: this.activeRoute})은 users / create에 대해서만 작동하지만 존재하지 않는 / users / edit / route로 이동하므로 users / edit / 123에는 작동하지 않습니다.
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ünter Zöchbauer

1
답변 주셔서 감사합니다.이 웹 사이트에서 꽤 오랫동안 작업 해 왔으므로 Angular는 그 이후로 분명히 업데이트되었습니다. 이 솔루션을 현재 버전에서 시도했지만 작동하지 않습니다. 업데이트하겠습니다. 나중에 다시 설명하겠습니다.
Carl Boisvert

1
코드가 예상대로 작동하지 않습니다. 그러나 탐색 호출에서 두 번째 매개 변수로 명시 적 으로 {relativeTo : this.route} 를 추가 하면 작동합니다. 귀하의 답변이 일반적으로 극도로 정확하다는 사실이 아니었다면 어리석은 오타로 분류하겠습니다. 대답이 제공된 이후 (3.6 년 전, Angular 년에는 반쯤 영원과 같은) 라우터 동작의 변화일까요?
Konrad Viltersten

이것은 오래된 답변이며 현재 라우터가 많이 변경되었습니다. 더 많은 찬성 투표가있는 답변이 여러 개 있다는 점을 고려할 때 내 답변은 구식이라고 생각합니다. 더 이상 웹 UI 작업을 그다지 많이하지 않고 머리 위에 모든 세부 정보가 없습니다.
Günter Zö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를 클릭하면 쿼리 매개 변수를 전달하고 구성 요소를로드합니다. 이제 브라우저 뒤로 버튼을 사용하여 돌아가려면 어떻게해야합니까?
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
  ) { }

3

별다른 고민없이 :

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

매개 변수 '..' 는 탐색을 한 단계 위로 만듭니다 . 즉, 상위 :)


skipLocationChange 의 목적 / 필요를 언급 할 수 있습니다 .
Konrad Viltersten

1

내 경로에는 다음과 같은 패턴이 있습니다.

  • user / edit / 1-> 편집
  • 사용자 / 만들기 / 0-> 만들기
  • 사용자 /-> 목록

예를 들어 편집 페이지에 있고 목록 페이지로 돌아 가야하는 경우 경로에서 2 단계 위로 돌아갑니다.

그것에 대해 생각하면서 "레벨"매개 변수로 메서드를 만들었습니다.

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

따라서 편집에서 목록으로 이동하려면 다음과 같은 메서드를 호출합니다.

this.goBack(2);

0

생성자에 위치 추가 @angular/common

constructor(private _location: Location) {}

뒤로 기능 추가 :

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

그리고 당신의 관점에서 :

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

5
이것은 이전에 상위 경로에 있었던 경우에만 작동합니다. 부모 노선 ... 브라우저 기록과는 아무 상관이 없다
leviathanbadger

그것은 다시 탐색하지만, 구성 요소의 부모로 이동하지 않습니다
앤드류 안드레에게

사용자가 외부 사이트에서 구성 요소로 이동하면 해당 사이트로 다시 가져 가게됩니다. 이 코드는 브라우저에서 뒤로 버튼을 클릭하는 것과 동일합니다.
T04435

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.