Respostas:
No Angular 2, você pode subscribe
(evento Rx) em uma instância do roteador. Então você pode fazer coisas como
class MyClass {
constructor(private router: Router) {
router.subscribe((val) => /*whatever*/)
}
}
Editar (desde rc.1)
class MyClass {
constructor(private router: Router) {
router.changes.subscribe((val) => /*whatever*/)
}
}
Edição 2 (desde 2.0.0)
veja também: Router.events doc
class MyClass {
constructor(private router: Router) {
router.events.subscribe((val) => {
// see also
console.log(val instanceof NavigationEnd)
});
}
}
filter
operador RxJS . router.events.pipe(filter(e => e instanceof NavigationEnd).subscribe((e) => { ... }
RxJS 6
router.events.pipe(filter(event => event instanceof NavigationStart))
Agradecimentos a Peilonrayz (veja os comentários abaixo)
novo roteador> = 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
});
}
Você também pode filtrar pelo evento especificado:
import 'rxjs/add/operator/filter';
constructor(router:Router) {
router.events
.filter(event => event instanceof NavigationStart)
.subscribe((event:NavigationStart) => {
// You only receive NavigationStart events
});
}
Usar o pairwise
operador para obter o evento anterior e atual também é uma boa ideia. 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
erro ocorre porque, no snippet de filtro, você está inscrevendo-se em um objeto do tipo Event em vez de NavigationEvent.
Para o Angular 7, alguém deve escrever como:
this.router.events.subscribe((event: Event) => {})
Um exemplo detalhado pode ser o seguinte:
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);
}
});
}
}
Angular 7 , se você quiser subscribe
pararouter
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);
});
}
Angular 4.xe acima:
Isso pode ser alcançado usando a propriedade url da classe ActivatedRoute como abaixo,
this.activatedRoute.url.subscribe(url =>{
console.log(url);
});
Nota:
Você precisa importar e injetar o provedor do angular/router
pacote
import { ActivatedRoute } from '@angular/router`
e
constructor(private activatedRoute : ActivatedRoute){ }
O roteador 3.0.0-beta.2 deve ser
this.router.events.subscribe(path => {
console.log('path = ', path);
});
No angular 6 e 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"
As respostas aqui estão corretas router-deprecated
. Para a versão mais recente do router
:
this.router.changes.forEach(() => {
// Do whatever in here
});
ou
this.router.changes.subscribe(() => {
// Do whatever in here
});
Para ver a diferença entre os dois, confira esta pergunta SO .
Editar
Para o mais recente, você deve fazer:
this.router.events.subscribe(event: Event => {
// Handle route change
});
router
foi atualizado novamente (ainda não atualizei minha resposta), por isso não tenho certeza de como é o último. Pelo router
que escrevi sobre, você não pôde. @akn
No Angular 8 você deve fazer como this.router.events.subscribe((event: Event) => {})
Exemplo:
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
}
});
}
}
No componente, você pode tentar o seguinte:
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
}
});
}
Capturar eventos de alteração de rota da seguinte maneira ...
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;
}
}
}
});
}
}
Localização funciona ...
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);
}
}
acima a maioria das soluções está correta, mas estou enfrentando um problema que é emitido várias vezes 'Navigation emit' event.when eu alterei qualquer rota, esse evento é acionado. Portanto, ouça é a solução completa para o 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();
}
}
A resposta do @Ludohen é ótima, mas caso você não queira usar, instanceof
use o seguinte
this.router.events.subscribe(event => {
if(event.constructor.name === "NavigationStart") {
// do something...
}
});
dessa maneira, você pode verificar o nome do evento atual como uma sequência e, se o evento ocorreu, pode fazer o que planejou sua função.
Event
tipo está causando um erro no Atom, é por isso que não o usei
instanceOf
esse código para que seu exemplo funcione também no código de produção. if(event instanceOf NavigationStart) {
if(event instanceof NavigationStart)
Estou trabalhando com o aplicativo angular5 e estou enfrentando o mesmo problema. Quando passo pela documentação angular, eles fornecem a melhor solução para lidar com os eventos do roteador. verifique a documentação a seguir.
Eventos de roteador em eventos de rota angular em angular5
Mas, especificamente para o caso, em questão, precisamos do NavigationEnd Event
Representa um evento acionado quando uma navegação termina com êxito
Como usar isso?
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");
}
});
}
}
Quando usar isso?
No meu caso, meu aplicativo compartilha um painel comum para todos os usuários, como usuários, Admins, mas preciso mostrar e ocultar algumas opções da barra de navegação conforme os tipos de usuário.
É por isso que sempre que a URL muda, eu preciso chamar o método de serviço, que retorna as informações do usuário logadas conforme a resposta, irei para outras operações.
O seguinte TIPO de obras e pode ser complicado para você.
// 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']);
});
Infelizmente, isso redireciona mais tarde no processo de roteamento do que eu gostaria. O onActivate()
componente de destino original é chamado antes do redirecionamento.
Existe um @CanActivate
decorador que você pode usar no componente de destino, mas este é a) não centralizado eb) não se beneficia dos serviços injetados.
Seria ótimo se alguém pudesse sugerir uma maneira melhor de autorizar centralmente uma rota antes que ela seja confirmada. Tenho certeza de que deve haver uma maneira melhor.
Este é o meu código atual (como eu o alteraria para ouvir a alteração de rota?):
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: '/'})]);
Eu faço assim desde RC 5
this.router.events
.map( event => event instanceof NavigationStart )
.subscribe( () => {
// TODO
} );
Basta fazer alterações no AppRoutingModule como
@NgModule({
imports: [RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled' })],
exports: [RouterModule]
})
Eu escreveria algo assim:
ngOnInit() {
this.routed = this.router.events.map( event => event instanceof NavigationStart )
.subscribe(() => {
} );
}
ngOnDestroy() {
this.routed.unsubscribe();
}
event._root.children[0].value._routeConfig.data
Espero que não pode haver melhor maneira