Respuestas:
En Angular 2 puede subscribe
(evento Rx) a una instancia de enrutador. Entonces puedes hacer cosas 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*/)
}
}
Edición 2 (desde 2.0.0)
ver también: 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))
Gracias a Peilonrayz (ver comentarios a continuación)
nuevo enrutador> = 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
});
}
También puede filtrar por evento dado:
import 'rxjs/add/operator/filter';
constructor(router:Router) {
router.events
.filter(event => event instanceof NavigationStart)
.subscribe((event:NavigationStart) => {
// You only receive NavigationStart events
});
}
Usar el pairwise
operador para obtener el evento anterior y actual también es una buena idea. 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
error se debe a que en el fragmento de filtro se está suscribiendo a un objeto de tipo Evento en lugar de NavigationEvent.
Para Angular 7, alguien debería escribir como:
this.router.events.subscribe((event: Event) => {})
Un ejemplo detallado puede ser el siguiente:
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 , si quieres subscribe
arouter
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.xy superior:
Esto se puede lograr usando la propiedad url de la clase ActivatedRoute como se muestra a continuación,
this.activatedRoute.url.subscribe(url =>{
console.log(url);
});
Nota:
que necesita importar e inyectar el proveedor del angular/router
paquete
import { ActivatedRoute } from '@angular/router`
y
constructor(private activatedRoute : ActivatedRoute){ }
Router 3.0.0-beta.2 debería ser
this.router.events.subscribe(path => {
console.log('path = ', path);
});
En angular 6 y 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"
Las respuestas aquí son correctas router-deprecated
. Para la última versión de router
:
this.router.changes.forEach(() => {
// Do whatever in here
});
o
this.router.changes.subscribe(() => {
// Do whatever in here
});
Para ver la diferencia entre los dos, consulte esta pregunta SO .
Editar
Para lo último debes hacer:
this.router.events.subscribe(event: Event => {
// Handle route change
});
router
ha actualizado nuevamente (aún no he actualizado mi respuesta), por lo que no estoy seguro de cómo es para la última. Por lo router
que escribí, no pudiste. @akn
En Angular 8 deberías hacer como this.router.events.subscribe((event: Event) => {})
Ejemplo:
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
}
});
}
}
En el componente, es posible que desee probar esto:
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
}
});
}
Capture eventos de cambio de ruta de la siguiente manera ...
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;
}
}
}
});
}
}
La ubicación 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);
}
}
arriba, la mayoría de las soluciones son correctas, pero estoy enfrentando un problema que emite varias veces el evento 'Navegación emitida'. Cuando cambié alguna ruta, este evento se activa. Entonces escuchar es la solución completa para 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();
}
}
La respuesta de @Ludohen es excelente, pero en caso de que no quiera usarla, instanceof
use lo siguiente
this.router.events.subscribe(event => {
if(event.constructor.name === "NavigationStart") {
// do something...
}
});
de esta manera, puede verificar el nombre del evento actual como una cadena y, si ocurrió el evento, puede hacer lo que planeó que hiciera su función.
Event
tipo está causando un error en Atom por eso no lo usé
instanceOf
para que su ejemplo también funcione en el código de producción. if(event instanceOf NavigationStart) {
if(event instanceof NavigationStart)
Estoy trabajando con la aplicación angular5 y estoy enfrentando el mismo problema. Cuando reviso la documentación angular, proporcionan la mejor solución para manejar los eventos del enrutador. Verifique la siguiente documentación.
Eventos de enrutador en eventos de ruta angular en angular5
Pero específicamente para el caso en cuestión, necesitamos el evento NavigationEnd
Representa un evento desencadenado cuando una navegación finaliza correctamente
Como usar esto ?
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");
}
});
}
}
¿Cuándo usar esto?
En mi caso, mi aplicación comparte un tablero común para todos los usuarios, como usuarios, administradores, pero necesito mostrar y ocultar algunas opciones de la barra de navegación según los tipos de usuarios.
Es por eso que cada vez que cambia la URL necesito llamar al método de servicio que devuelve la información de usuario registrada según la respuesta, iré para más operaciones.
El siguiente TIPO de trabajos y puede hacer el truco para usted.
// 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']);
});
Desafortunadamente, esto redirige más tarde en el proceso de enrutamiento de lo que me gustaría. losonActivate()
del componente de destino original se llama antes de la redirección.
Hay un @CanActivate
decorador que puede usar en el componente de destino, pero este es a) no centralizado yb) no se beneficia de los servicios inyectados.
Sería genial si alguien puede sugerir una mejor manera de autorizar centralmente una ruta antes de que se comprometa. Estoy seguro de que debe haber una mejor manera.
Este es mi código actual (¿Cómo lo cambiaría para escuchar el cambio de ruta?):
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: '/'})]);
Lo hago así desde RC 5
this.router.events
.map( event => event instanceof NavigationStart )
.subscribe( () => {
// TODO
} );
Simplemente haga cambios en AppRoutingModule como
@NgModule({
imports: [RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled' })],
exports: [RouterModule]
})
Escribiría algo como esto:
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 haya una mejor manera