Risposte:
In Angular 2 è possibile subscribe(evento Rx) a un'istanza del router. Quindi puoi fare cose del genere
class MyClass {
constructor(private router: Router) {
router.subscribe((val) => /*whatever*/)
}
}
Modifica (dal rc.1)
class MyClass {
constructor(private router: Router) {
router.changes.subscribe((val) => /*whatever*/)
}
}
Modifica 2 (dalla 2.0.0)
vedi anche: Router.events doc
class MyClass {
constructor(private router: Router) {
router.events.subscribe((val) => {
// see also
console.log(val instanceof NavigationEnd)
});
}
}
filteroperatore RxJS . router.events.pipe(filter(e => e instanceof NavigationEnd).subscribe((e) => { ... }
RxJS 6
router.events.pipe(filter(event => event instanceof NavigationStart))
Grazie a Peilonrayz (vedi commenti sotto)
nuovo router> = 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
});
}
Puoi anche filtrare per evento dato:
import 'rxjs/add/operator/filter';
constructor(router:Router) {
router.events
.filter(event => event instanceof NavigationStart)
.subscribe((event:NavigationStart) => {
// You only receive NavigationStart events
});
}
Anche usare l' pairwiseoperatore per ottenere l'evento precedente e attuale è una buona 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 typeerrore è dovuto al fatto che nel tuo frammento di filtro stai sottoscrivendo un oggetto di tipo Event anziché NavigationEvent.
Per Angular 7 qualcuno dovrebbe scrivere come:
this.router.events.subscribe((event: Event) => {})
Un esempio dettagliato può essere il seguente:
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);
}
});
}
}
Angolare 7 , se si vuole subscribearouter
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);
});
}
Angolare 4.xe versioni successive:
Ciò può essere ottenuto utilizzando la proprietà url della classe ActivatedRoute come di seguito,
this.activatedRoute.url.subscribe(url =>{
console.log(url);
});
Nota:
è necessario importare e iniettare il provider dal angular/routerpacchetto
import { ActivatedRoute } from '@angular/router`
e
constructor(private activatedRoute : ActivatedRoute){ }
Il router 3.0.0-beta.2 dovrebbe essere
this.router.events.subscribe(path => {
console.log('path = ', path);
});
In angolare 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"
Le risposte qui sono corrette per router-deprecated. Per l'ultima versione di router:
this.router.changes.forEach(() => {
// Do whatever in here
});
o
this.router.changes.subscribe(() => {
// Do whatever in here
});
Per vedere la differenza tra i due, controlla questa domanda SO .
modificare
Per l'ultimo devi fare:
this.router.events.subscribe(event: Event => {
// Handle route change
});
routerstato aggiornato di nuovo (non ho ancora aggiornato la mia risposta), quindi non sono sicuro di come sia l'ultima. Per quello di cui routerho scritto, non puoi. @akn
In Angular 8 dovresti fare come this.router.events.subscribe((event: Event) => {})
Esempio:
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
}
});
}
}
Nel componente, potresti provare questo:
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
}
});
}
Cattura gli eventi di cambio di rotta nel modo seguente ...
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 posizione funziona ...
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);
}
}
sopra la maggior parte delle soluzioni corrette, ma sto affrontando questo problema emettere più volte l'evento "Emissione navigazione". Quando stavo cambiando qualsiasi rotta questo evento viene attivato. Quindi ascoltare è la soluzione completa per 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 risposta di @Ludohen è ottima, ma nel caso in cui non si desideri utilizzare instanceofutilizzare quanto segue
this.router.events.subscribe(event => {
if(event.constructor.name === "NavigationStart") {
// do something...
}
});
in questo modo puoi controllare il nome dell'evento corrente come una stringa e se l'evento si è verificato puoi fare ciò che hai pianificato per la tua funzione.
Eventtipo sta causando un errore in Atom ed è per questo che non l'ho usato
instanceOfmodo che anche il tuo esempio funzioni nel codice di produzione. if(event instanceOf NavigationStart) {
if(event instanceof NavigationStart)
Sto lavorando con l'applicazione angular5 e sto affrontando lo stesso problema. quando passo attraverso la documentazione angolare forniscono la migliore soluzione per la gestione degli eventi del router. Controlla la seguente documentazione.
Eventi router in Angular Route eventi in angular5
Ma specificamente per il caso in questione abbiamo bisogno di NavigationEnd Event
Rappresenta un evento attivato quando una navigazione termina correttamente
Come usare questo?
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 usarlo?
Nel mio caso la mia applicazione condivide dashboard comune per tutti gli utenti come utenti, amministratori, ma devo mostrare e nascondere alcune opzioni della barra di navigazione in base ai tipi di utenti.
Ecco perché ogni volta che l'URL cambia, devo chiamare il metodo di servizio che restituisce le informazioni dell'utente registrato come da risposta, andrò per ulteriori operazioni.
Il seguente tipo di opere e può fare il difficile per te.
// 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']);
});
Purtroppo questo reindirizza più tardi nel processo di routing di quanto vorrei. IlonActivate() componente di destinazione originale viene chiamato prima del reindirizzamento.
C'è un @CanActivate decoratore che puoi usare sul componente target ma questo è a) non centralizzato eb) non beneficia dei servizi iniettati.
Sarebbe bello se qualcuno potesse suggerire un modo migliore di autorizzare centralmente un percorso prima che venga eseguito. Sono sicuro che ci deve essere un modo migliore.
Questo è il mio codice attuale (come lo cambierei per ascoltare il cambio di rotta?):
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 faccio così da RC 5
this.router.events
.map( event => event instanceof NavigationStart )
.subscribe( () => {
// TODO
} );
Apporta semplicemente modifiche su AppRoutingModule come
@NgModule({
imports: [RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled' })],
exports: [RouterModule]
})
Scriverei qualcosa del genere:
ngOnInit() {
this.routed = this.router.events.map( event => event instanceof NavigationStart )
.subscribe(() => {
} );
}
ngOnDestroy() {
this.routed.unsubscribe();
}
event._root.children[0].value._routeConfig.datasperando che ci possa essere un modo migliore