답변:
Angular 2에서는 subscribe
라우터 인스턴스에 (Rx 이벤트)를 할 수 있습니다 . 그래서 당신은 같은 일을 할 수 있습니다
class MyClass {
constructor(private router: Router) {
router.subscribe((val) => /*whatever*/)
}
}
편집 (rc.1부터)
class MyClass {
constructor(private router: Router) {
router.changes.subscribe((val) => /*whatever*/)
}
}
2 편집 (2.0.0부터)
참조 : Router.events doc
class MyClass {
constructor(private router: Router) {
router.events.subscribe((val) => {
// see also
console.log(val instanceof NavigationEnd)
});
}
}
filter
연산자로 이벤트를 쉽게 필터링 할 수 있습니다 . router.events.pipe(filter(e => e instanceof NavigationEnd).subscribe((e) => { ... }
RxJS 6
router.events.pipe(filter(event => event instanceof NavigationStart))
Peilonrayz 덕분에 (아래 의견 참조)
새 라우터> = RC.3
import { Router, NavigationStart, NavigationEnd, NavigationError, NavigationCancel, RoutesRecognized } from '@angular/router';
constructor(router:Router) {
router.events.forEach((event) => {
if(event instanceof NavigationStart) {
}
// NavigationEnd
// NavigationCancel
// NavigationError
// RoutesRecognized
});
}
주어진 이벤트로 필터링 할 수도 있습니다.
import 'rxjs/add/operator/filter';
constructor(router:Router) {
router.events
.filter(event => event instanceof NavigationStart)
.subscribe((event:NavigationStart) => {
// You only receive NavigationStart events
});
}
pairwise
연산자 를 사용하여 이전 및 현재 이벤트를 얻는 것도 좋은 생각입니다. https://github.com/angular/angular/issues/11268#issuecomment-244601977
import 'rxjs/add/operator/pairwise'; import { Router } from '@angular/router; export class AppComponent { constructor(private router: Router) { this.router.events.pairwise().subscribe((event) => { console.log(event); }); }; }
Argument of type '(event: Event) => void' is not assignable to parameter of type
Argument of type '(event: Event) => void' is not assignable to parameter of type
오류는 필터 스 니펫에서 NavigationEvent 대신 Event 유형의 객체를 구독하고 있기 때문입니다.
들어 각도 일곱 사람이 같이 작성해야합니다 :
this.router.events.subscribe((event: Event) => {})
자세한 예는 다음과 같습니다.
import { Component } from '@angular/core';
import { Router, Event, NavigationStart, NavigationEnd, NavigationError } from '@angular/router';
@Component({
selector: 'app-root',
template: `<router-outlet></router-outlet>`
})
export class AppComponent {
constructor(private router: Router) {
this.router.events.subscribe((event: Event) => {
if (event instanceof NavigationStart) {
// Show loading indicator
}
if (event instanceof NavigationEnd) {
// Hide loading indicator
}
if (event instanceof NavigationError) {
// Hide loading indicator
// Present error to user
console.log(event.error);
}
});
}
}
7 각도 , 당신이 원하는 경우 subscribe
에router
import { Router, NavigationEnd } from '@angular/router';
import { filter } from 'rxjs/operators';
constructor(
private router: Router
) {
router.events.pipe(
filter(event => event instanceof NavigationEnd)
).subscribe((event: NavigationEnd) => {
console.log(event.url);
});
}
각도 4.x 이상 :
이것은 아래와 같이 ActivatedRoute 클래스 의 url 속성을 사용하여 달성 할 수 있습니다 .
this.activatedRoute.url.subscribe(url =>{
console.log(url);
});
참고 :angular/router
패키지
에서 공급자를 가져 와서 주입해야 합니다.
import { ActivatedRoute } from '@angular/router`
과
constructor(private activatedRoute : ActivatedRoute){ }
각도 6 및 RxJS6에서 :
import { filter, debounceTime } from 'rxjs/operators';
this.router.events.pipe(
filter((event) => event instanceof NavigationEnd),
debounceTime(40000)
).subscribe(
x => {
console.log('val',x);
this.router.navigate(['/']); /*Redirect to Home*/
}
)
import {Router, NavigationEnd} from "@angular/router"
여기에 대한 답변이 옳습니다 router-deprecated
. 최신 버전 router
:
this.router.changes.forEach(() => {
// Do whatever in here
});
또는
this.router.changes.subscribe(() => {
// Do whatever in here
});
이 둘의 차이점을 확인하려면 이 SO 질문을 확인하십시오 .
편집하다
최신의 경우 다음을 수행해야합니다.
this.router.events.subscribe(event: Event => {
// Handle route change
});
router
다시 업데이트되었습니다 (아직 답변을 업데이트하지 않았습니다). 최신 업데이트 방법이 확실하지 않습니다. 를 들어 router
내가 쓴, 당신은 할 수 없습니다. @akn
Angular 8에서는 다음과 같이해야합니다. this.router.events.subscribe((event: Event) => {})
예:
import { Component } from '@angular/core';
import { Router, Event } from '@angular/router';
import { NavigationStart, NavigationError, NavigationEnd } from '@angular/router';
@Component({
selector: 'app-root',
template: `<router-outlet></router-outlet>`
})
export class AppComponent {
constructor(private router: Router) {
//Router subscriber
this.router.events.subscribe((event: Event) => {
if (event instanceof NavigationStart) {
//do something on start activity
}
if (event instanceof NavigationError) {
// Handle error
console.error(event.error);
}
if (event instanceof NavigationEnd) {
//do something on end activity
}
});
}
}
컴포넌트에서 다음을 시도 할 수 있습니다.
import {NavigationEnd, NavigationStart, Router} from '@angular/router';
constructor(private router: Router) {
router.events.subscribe(
(event) => {
if (event instanceof NavigationStart)
// start loading pages
if (event instanceof NavigationEnd) {
// end of loading paegs
}
});
}
다음과 같은 방법으로 경로 변경 이벤트를 캡처하십시오.
import { Component, OnInit, Output, ViewChild } from "@angular/core";
import { Router, NavigationStart, NavigationEnd, Event as NavigationEvent } from '@angular/router';
@Component({
selector: "my-app",
templateUrl: "app/app.component.html",
styleUrls: ["app/app.component.css"]
})
export class AppComponent {
constructor(private cacheComponentObj: CacheComponent,
private router: Router) {
/* Route event types
NavigationEnd
NavigationCancel
NavigationError
RoutesRecognized
*/
router.events.forEach((event: NavigationEvent) => {
//Before Navigation
if (event instanceof NavigationStart) {
switch (event.url) {
case "/app/home":
{
//Do Work
break;
}
case "/app/About":
{
//Do Work
break;
}
}
}
//After Navigation
if (event instanceof NavigationEnd) {
switch (event.url) {
case "/app/home":
{
//Do Work
break;
}
case "/app/About":
{
//Do Work
break;
}
}
}
});
}
}
위치는 작동합니다 ...
import {Component, OnInit} from '@angular/core';
import {Location} from '@angular/common';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
constructor(private location: Location) {
this.location.onUrlChange(x => this.urlChange(x));
}
ngOnInit(): void {}
urlChange(x) {
console.log(x);
}
}
위의 대부분의 솔루션은 정확하지만 문제가 발생했습니다 .'Navigation emit '이벤트가 여러 번 발생합니다. 경로를 변경하면이 이벤트가 트리거됩니다. 따라서 Angular 6의 완벽한 솔루션입니다.
import { Subscription } from 'rxjs/Subscription';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/filter';
export class FooComponent implements OnInit, OnDestroy {
private _routerSub = Subscription.EMPTY;
constructor(private router: Router){}
ngOnInit(){
this._routerSub = this.router.events
.filter(event => event instanceof NavigationEnd)
.subscribe((value) => {
//do something with the value
});
}
ngOnDestroy(){
this._routerSub.unsubscribe();
}
}
@Ludohen 답변은 훌륭하지만 사용하지 않으려는 경우 instanceof
다음을 사용하십시오.
this.router.events.subscribe(event => {
if(event.constructor.name === "NavigationStart") {
// do something...
}
});
이 방법으로 현재 이벤트 이름을 문자열로 확인할 수 있으며 이벤트가 발생한 경우 기능 계획을 수행 할 수 있습니다.
Event
형은 내가 그것을 사용하지 않은 이유 아톰의 오류의 원인이되는
instanceOf
되므로 예제를 프로덕션 코드에서도 작동하도록 사용해야 합니다. if(event instanceOf NavigationStart) {
if(event instanceof NavigationStart)
angular5 응용 프로그램으로 작업 중이며 같은 문제에 직면하고 있습니다. Angular Documentation을 살펴보면 라우터 이벤트를 처리하는 최상의 솔루션을 제공합니다. 다음 설명서를 확인하십시오.
angular5의 앵귤러 라우트 이벤트에서의 라우터 이벤트
그러나 특히 문제가있는 경우 NavigationEnd 이벤트 가 필요합니다.
탐색이 성공적으로 종료 될 때 트리거되는 이벤트를 나타냅니다.
이것을 사용하는 방법?
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRouteSnapshot, NavigationEnd } from '@angular/router';
@Component({
selector: 'app-navbar',
templateUrl: './navbar.component.html',
styleUrls: ['./navbar.component.css']
})
export class NavbarComponent implements OnInit {
constructor(private router: Router) { }
ngOnInit(): void {
//calls this method when navigation ends
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
//calls this stuff when navigation ends
console.log("Event generated");
}
});
}
}
이것을 언제 사용합니까?
필자의 경우 내 응용 프로그램은 users, Admins와 같은 모든 사용자에게 공통 대시 보드를 공유하지만 사용자 유형별로 일부 탐색 표시 줄 옵션을 표시하고 숨겨야합니다.
그래서 URL이 변경 될 때마다 응답별로 로그인 한 사용자 정보를 반환하는 서비스 메소드를 호출해야합니다. 추가 작업을 수행합니다.
다음과 같은 종류의 작품이 당신을 위해 까다로울 수 있습니다.
// in constructor of your app.ts with router and auth services injected
router.subscribe(path => {
if (!authService.isAuthorised(path)) //whatever your auth service needs
router.navigate(['/Login']);
});
불행히도 이것은 라우팅 프로세스에서 나중에 원하는 것보다 리디렉션됩니다. 그만큼onActivate()
원래 대상 구성 요소의이 리디렉션하기 전에 호출된다.
이있다 @CanActivate
대상 구성 요소에 사용할 수 데코레이터 있지만 a) 중앙 집중식이 아니며 b) 주입 된 서비스의 이점이 없습니다.
경로가 커밋되기 전에 중앙에서 권한을 부여하는 더 나은 방법을 제안 할 수 있다면 좋을 것입니다. 더 좋은 방법이 있어야합니다.
이것은 현재 코드입니다 (경로 변경을 청취하려면 어떻게 변경합니까?) :
import {Component, View, bootstrap, bind, provide} from 'angular2/angular2';
import {ROUTER_BINDINGS, RouterOutlet, RouteConfig, RouterLink, ROUTER_PROVIDERS, APP_BASE_HREF} from 'angular2/router';
import {Location, LocationStrategy, HashLocationStrategy} from 'angular2/router';
import { Todo } from './components/todo/todo';
import { About } from './components/about/about';
@Component({
selector: 'app'
})
@View({
template: `
<div class="container">
<nav>
<ul>
<li><a [router-link]="['/Home']">Todo</a></li>
<li><a [router-link]="['/About']">About</a></li>
</ul>
</nav>
<router-outlet></router-outlet>
</div>
`,
directives: [RouterOutlet, RouterLink]
})
@RouteConfig([
{ path: '/', redirectTo: '/home' },
{ path: '/home', component: Todo, as: 'Home' },
{ path: '/about', component: About, as: 'About' }
])
class AppComponent {
constructor(location: Location){
location.go('/');
}
}
bootstrap(AppComponent, [ROUTER_PROVIDERS, provide(APP_BASE_HREF, {useValue: '/'})]);
나는 이런 식으로 쓸 것이다 :
ngOnInit() {
this.routed = this.router.events.map( event => event instanceof NavigationStart )
.subscribe(() => {
} );
}
ngOnDestroy() {
this.routed.unsubscribe();
}
event._root.children[0].value._routeConfig.data
내가 더 나은 방법이 될 수 있기를 바랍니다