Angular에서 이전 페이지 URL을 확인하는 방법은 무엇입니까?


104

현재 URL이있는 페이지에 있다고 가정합니다 /user/:id. 이제이 페이지에서 다음 페이지로 이동합니다 :id/posts.

이제 방법이 있습니까? 그러면 이전 URL이 무엇인지 확인할 수 있습니다 /user/:id.

아래는 내 경로입니다

export const routes: Routes = [
  { 
    path: 'user/:id', component: UserProfileComponent
  },
  {  
    path: ':id/posts', component: UserPostsComponet 
  }
];

답변:


83

경로 변경을 구독하고 현재 이벤트를 저장하여 다음에 발생할 때 사용할 수 있습니다.

previousUrl: string;
constructor(router: Router) {
  router.events
  .pipe(filter(event => event instanceof NavigationEnd))
  .subscribe((event: NavigationEnd) => {
    console.log('prev:', event.url);
    this.previousUrl = event.url;
  });
}

Angular에서 경로 변경을 감지하는 방법을 참조하십시오 .


12
감사합니다 @ Günter 당신은 항상 내 하루를 저장합니다.
— Chandra Shekhar

34
이것은 나를위한 이전 경로가 아니라 현재 경로 만 나열합니다.
— 데이비드 아구

2
당신이 기대하는 것에 달려 있습니다. 처음 null에는 이전 경로가 없기 때문입니다. 루트 라우터에서도이 작업을 수행해야합니다. 그렇지 않으면이 구성 요소의 하위 경로 사이를 탐색 할 때만 얻을 수 있습니다.
— Günter Zöchbauer 2017

8
생성자가 처음 실행될 때 이전 URL을 제공하지 않습니다.
— Ekaitz Hernandez Troyas

9
생성자가 처음 실행될 때 이전 URL로 어떤 값을 기대합니까?
— Günter Zöchbauer

114

아마도 다른 모든 대답은 각도 2.X에 대한 것입니다.

이제 각도 5.X에서는 작동하지 않습니다. 나는 그것으로 일하고있다.

NavigationEnd 만 있으면 이전 URL을 가져올 수 없습니다.

라우터는 "NavigationStart", "RoutesRecognized", ..., "NavigationEnd"에서 작동하기 때문입니다.

당신은 확인할 수 있습니다

    router.events.forEach((event) => {
  console.log(event);
});

그러나 여전히 "NavigationStart"를 사용해도 이전 URL을 가져올 수 없습니다.

이제 pairwise를 사용해야합니다.

import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/pairwise';

constructor(private router: Router) {
  this.router.events
    .filter(e => e instanceof RoutesRecognized)
    .pairwise()
    .subscribe((event: any[]) => {
      console.log(event[0].urlAfterRedirects);
    });
}
    

pairwise를 사용하면 어떤 URL이 시작되고 있는지 확인할 수 있습니다.

"RoutesRecognized"는 출발지에서 타겟 URL로 변경하는 단계입니다.

그래서 그것을 필터링하고 그것에서 이전 URL을 가져옵니다.

마지막으로,

이 코드를 상위 구성 요소 이상 (예 : app.component.ts)에 넣습니다.

이 코드는 라우팅을 마친 후에 실행되기 때문입니다.

각도 업데이트 6+

이 events.filter필터는 이벤트의 일부가 아니므로 코드를 변경 때문에 오류를 제공

import { filter, pairwise } from 'rxjs/operators';

this.router.events
.pipe(filter((evt: any) => evt instanceof RoutesRecognized), pairwise())
.subscribe((events: RoutesRecognized[]) => {
  console.log('previous url', events[0].urlAfterRedirects);
  console.log('current url', events[1].urlAfterRedirects);
});

2
서비스로 구현되었으며 훌륭하게 작동합니다. 각도 6.1.7을 사용하고 있습니다.
— A. El Idrissi

5
@ tjvg1991 페이지를 새로 고치면 메모리 데이터가 손실되었습니다. 이전 데이터를 유지하는 경우 localStorage 또는 쿠키를 사용해야합니다. (메모리가 아닌 로컬에 데이터 저장)
— 진병 주

@BYUNGJUJIN 감사합니다!
— john

1
의 반환 값을 저장 @BYUNGJUIN subscribe()필드 및 통화 unsubscribe()에에 ngOnDestroy(). 서버가 있어야합니다. 여기에서 구독 취소에 대한 예가 담긴 질문.
— Günter Zöchbauer

1
: Google Play 무비 구독 취소이 확인하시기 바랍니다 malcontentboffin.com/2017/12/...
— BYUNGJU JIN

51

주입 가능한 서비스를 만듭니다.

import { Injectable } from '@angular/core';
import { Router, RouterEvent, NavigationEnd } from '@angular/router';

 /** A router wrapper, adding extra functions. */
@Injectable()
export class RouterExtService {

  private previousUrl: string = undefined;
  private currentUrl: string = undefined;

  constructor(private router : Router) {
    this.currentUrl = this.router.url;
    router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {        
        this.previousUrl = this.currentUrl;
        this.currentUrl = event.url;
      };
    });
  }

  public getPreviousUrl(){
    return this.previousUrl;
  }    
}

그런 다음 필요한 모든 곳에서 사용하십시오. 현재 변수를 가능한 한 빨리 저장하려면 AppModule에서 서비스를 사용해야합니다.

// AppModule
export class AppModule {
  constructor(private routerExtService: RouterExtService){}

  //...

}

// Using in SomeComponent
export class SomeComponent implements OnInit {

  constructor(private routerExtService: RouterExtService, private location: Location) { } 

  public back(): void {
    this.location.back();
  }

  //Strange name, but it makes sense. Behind the scenes, we are pushing to history the previous url
  public goToPrevious(): void {
    let previous = this.routerExtService.getPreviousUrl();

    if(previous)
      this.routerExtService.router.navigateByUrl(previous);
  }

  //...

}

2
나는 이것이 가장 우아한 해결책이라고 생각합니다. 이 코드를 새로운 필터 및 쌍별 솔루션과 병합하십시오. stackoverflow.com/a/35287471/518879
— danger89

2
추신. 다음과 같이이 RouterExtService를 apps-routing.module.ts (내 경우)에 추가하는 것을 잊지 마십시오.@NgModule({ ..., providers: [RouterExtService]}) export class AppRoutingModule { }
— danger89

이 서비스 솔루션에 큰 문제가 있습니다. 제 경우 routerExtService.getPreviousUrl()에는 컴포넌트에서 사용되는 서비스의 생성자 에서 메소드를 호출합니다 . 어떤 이유로 실제 업데이트보다 일찍 호출되었습니다. 타이밍 의존성이 있다는 뜻입니다! 주제를 사용하는 것이 훨씬 쉽다고 생각합니다.
— danger89

음, 작은 프로젝트에서 잘 작동했습니다. 필요에 맞게 약간의 조정이 필요할 수 있습니다. 문제를 해결 했습니까?
— Juliano

현재 내 URL에 내 상태를 '저장'하기 위해 소위 URL Matrix 매개 변수 를 사용하고 있습니다. 기본적으로 브라우저 URL은 뒤로 버튼을 사용할 때 상태를 저장합니다. let params = new HttpParams({fromString: retrieveURL}).set('name', 'victor') const paramsObject = params.keys().reduce((obj, key) => { obj[key] = params.get(key) return obj }, {}) this.router.navigate([paramsObject], { relativeTo: this.route })
— danger89

20

이전 URL을 문자열로 가져 오기위한 Angular 6 업데이트 코드.

import { Router, RoutesRecognized } from '@angular/router';
import { filter, pairwise } from 'rxjs/operators';


export class AppComponent implements OnInit {

    constructor (
        public router: Router
    ) {
    }

    ngOnInit() {
        this.router.events
            .pipe(filter((e: any) => e instanceof RoutesRecognized),
                pairwise()
            ).subscribe((e: any) => {
                console.log(e[0].urlAfterRedirects); // previous url
            });
    }

이것은 가드에 의해 차단 된 URL을 반환합니다. 활성화 된 이전 URL 만 가져올 수있는 방법이 있습니까 (가드에 의해 차단되지 않음)?
— Exocomp

1
라우터에서 구독을 취소하는 가장 좋은 방법에 대한 힌트가 있습니까?
— j4v1

공장! "NavigationEnd는"하지 작업 않는 이유를 정말 모르겠다
— davidwillianx

13

이것은 각도> = 6.x 버전에서 나를 위해 일했습니다.

this.router.events
            .subscribe((event) => {
              if (event instanceof NavigationStart) {
                window.localStorage.setItem('previousUrl', this.router.url);
              }
            });

11

내가 사용하고 각도 (8) 와 프랭클린 - 경건한을 해결해 @ 문제의 답을. 제 경우에는 구독 내에서 이전 URL을 가져 오면 뷰의 일부 데이터가 첨부되면 부작용이 발생합니다.

내가 사용한 해결 방법은 경로 탐색에서 이전 URL을 선택적 매개 변수로 보내는 것입니다.

this.router.navigate(['/my-previous-route', {previousUrl: 'my-current-route'}])

구성 요소에서이 값을 얻으려면 :

this.route.snapshot.paramMap.get('previousUrl')

this.router 및 this.route는 각 구성 요소의 생성자 내부에 삽입되고 @ angular / router 멤버로 가져옵니다.

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

10

Angular 8 및 rxjs 6 (2019 버전)

다른 훌륭한 솔루션을 기반으로 솔루션을 공유하고 싶습니다.

먼저 경로 변경을 수신하는 서비스를 만들고 Behavior Subject에 마지막 이전 경로를 저장 한 다음 생성자의 주 app.component에이 서비스를 제공 한 다음이 서비스를 사용하여 원하는 때에 원하는 이전 경로를 가져옵니다.

사용 사례 : 사용자를 광고 페이지로 리디렉션 한 다음 사용자가 원래 있던 위치로 자동 리디렉션하므로 마지막 이전 경로가 필요합니다.

// service : route-events.service.ts

import { Injectable } from '@angular/core';
import { Router, RoutesRecognized } from '@angular/router';
import { BehaviorSubject } from 'rxjs';
import { filter, pairwise } from 'rxjs/operators';
import { Location } from '@angular/common';

@Injectable()
export class RouteEventsService {

    // save the previous route
  public previousRoutePath = new BehaviorSubject<string>('');

  constructor(
    private router: Router,
    private location: Location
  ) {

    // ..initial prvious route will be the current path for now
    this.previousRoutePath.next(this.location.path());


    // on every route change take the two events of two routes changed(using pairwise)
    // and save the old one in a behavious subject to access it in another component
    // we can use if another component like intro-advertise need the previous route
    // because he need to redirect the user to where he did came from.
    this.router.events.pipe(
      filter(e => e instanceof RoutesRecognized),
      pairwise(),
        )
    .subscribe((event: any[]) => {
        this.previousRoutePath.next(event[0].urlAfterRedirects);
    });

  }
}

app.module에서 서비스 제공

  providers: [
    ....
    RouteEventsService,
    ....
  ]

app.component에 삽입

  constructor(
    private routeEventsService: RouteEventsService
  )

마지막으로 원하는 구성 요소에서 저장된 이전 경로를 사용하십시오.

  onSkipHandler(){
    // navigate the user to where he did came from
    this.router.navigate([this.routeEventsService.previousRoutePath.value]);
  }

이것은 정말 잘 작동합니다. 하지만 빠른 질문이 있습니다. 구독을 취소 한 적이 있습니까?
— w0ns88

add take (1) like
— this-

1
@Injectable({ providedIn: 'root' })서비스 를 사용 하면 프로젝트의 루트 모듈 (AppModule)에 자동으로로드되므로 .NET Framework에 수동으로 제공 할 필요가 없습니다 app.module. 자세한 내용 은 문서 를 참조하십시오. 이 답변에
— Hkidd

7

ANGULAR 7+

실제로 Angular 7.2 이후에는 이전 URL을 저장하기 위해 서비스를 사용할 필요가 없습니다. 로그인 페이지에 연결하기 전에 상태 개체를 사용하여 마지막 URL을 설정할 수 있습니다. 다음은 로그인 시나리오의 예입니다.

@Component({ ... })
class SomePageComponent {
  constructor(private router: Router) {}

  checkLogin() {
    if (!this.auth.loggedIn()) {
      this.router.navigate(['login'], { state: { redirect: this.router.url } });
    }
  }
}
@Component({...})
class LoginComponent {
  constructor(private router: Router) {}

  backToPreviousPage() {
    const { redirect } = window.history.state;

    this.router.navigateByUrl(redirect || '/homepage');
  }
}
----------------

또한 템플릿의 데이터를 전달할 수도 있습니다.

@Component({
  template: '<a routerLink="/some-route" [state]="{ redirect: router.url}">Go to some route</a>'
})
class SomePageComponent {
  constructor(public router: Router) {}
}

3

@ GünterZöchbauer 또한 localstorage에 저장할 수 있지만 선호하지 않습니다.) 서비스에 저장하고 거기 에서이 값을 얻는 것이 좋습니다.

 constructor(
        private router: Router
      ) {
        this.router.events
          .subscribe((event) => {
            if (event instanceof NavigationEnd) {
              localStorage.setItem('previousUrl', event.url);
            }
          });
      }

3

언급 한대로 위치를 사용할 수 있습니다. 여기에 .

링크가 새 탭에서 열린 경우 내 코드는 다음과 같습니다.

navBack() {
    let cur_path = this.location.path();
    this.location.back();
    if (cur_path === this.location.path())
     this.router.navigate(['/default-route']);    
  }

필수 수입품

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

0

previousNavigation객체 를 사용하면 매우 간단 합니다.

this.router.events
  .pipe(
    filter(e => e instanceof NavigationEnd && this.router.getCurrentNavigation().previousNavigation),
    map(() => this.router.getCurrentNavigation().previousNavigation.finalUrl.toString()),
  )
  .subscribe(previousUrl => {}); 

0

경비원 내부에서 이전 URL에 액세스하는 데 어려움을 겪었습니다.
사용자 지정 솔루션을 구현하지 않으면이 솔루션이 저에게 효과적입니다.

public constructor(private readonly router: Router) {
};

public ngOnInit() {
   this.router.getCurrentNavigation().previousNavigation.initialUrl.toString();
}

초기 URL은 이전 URL 페이지가됩니다.


0

이 간단한 솔루션이 저에게 효과적이었습니다.

import 'rxjs/add/operator/pairwise';
import { Router } from '@angular/router';

export class TempComponent {
    constructor(private router: Router) {
        this.router.events.pairwise().subscribe((event) => {
            console.log(event); // NavigationEnd will have last and current visit url
        });
    };
}


-2

rxjx에서 pairwise를 사용하면이 작업을 더 쉽게 수행 할 수 있습니다. import {filter, pairwise} from 'rxjs / operators';

previousUrl: string;
constructor(router: Router) {
router.events
  .pipe(filter((evt: any) => evt instanceof RoutesRecognized), pairwise())
  .subscribe((events: RoutesRecognized[]) => {
  console.log('previous url', events[0].urlAfterRedirects);
  console.log('current url', events[1].urlAfterRedirects);
  this.previousUrl = events[0].urlAfterRedirects;
});

}


-6

이전 페이지로 돌아가고 싶을 때 비슷한 문제가 발생했습니다. 솔루션은 제가 상상할 수있는 것보다 쉬웠습니다.

<button [routerLink]="['../']">
   Back
</button>

그리고 부모 URL로 돌아갑니다. 누군가를 도울 수 있기를 바랍니다.)


이것은 작동하지 않을 것입니다. OP가 말한 것처럼 이전 URL이 아닌 라우터의 경로로 이동하라는 것입니다.
— Frederic Yesid Peña Sánchez

URL이 매개 변수로 복잡하거나 상위 경로와 동일한 경로가없는 경우에는 작동하지 않습니다. "무언가 / 부모 / 자식"에서 "무언가 / 부모"로 돌아 가려는 경우에만 작동합니다.
— A. El Idrissi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.