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


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.