Antworten:
In Angular 2 können Sie subscribe
(Rx-Ereignis) zu einer Router-Instanz. So können Sie Dinge wie tun
class MyClass {
constructor(private router: Router) {
router.subscribe((val) => /*whatever*/)
}
}
Bearbeiten (seit rc.1)
class MyClass {
constructor(private router: Router) {
router.changes.subscribe((val) => /*whatever*/)
}
}
Bearbeiten 2 (seit 2.0.0)
Siehe auch: Router.events doc
class MyClass {
constructor(private router: Router) {
router.events.subscribe((val) => {
// see also
console.log(val instanceof NavigationEnd)
});
}
}
filter
Operator filtern . router.events.pipe(filter(e => e instanceof NavigationEnd).subscribe((e) => { ... }
RxJS 6
router.events.pipe(filter(event => event instanceof NavigationStart))
Vielen Dank an Peilonrayz (siehe Kommentare unten)
neuer 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
});
}
Sie können auch nach dem angegebenen Ereignis filtern:
import 'rxjs/add/operator/filter';
constructor(router:Router) {
router.events
.filter(event => event instanceof NavigationStart)
.subscribe((event:NavigationStart) => {
// You only receive NavigationStart events
});
}
Es ist auch eine gute Idee, den pairwise
Operator zu verwenden, um das vorherige und aktuelle Ereignis abzurufen. 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
Fehler liegt darin, dass Sie in Ihrem Filter-Snippet ein Objekt vom Typ Event anstelle von NavigationEvent abonnieren.
Für Angular 7 sollte jemand schreiben wie:
this.router.events.subscribe((event: Event) => {})
Ein detailliertes Beispiel kann wie folgt sein:
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 , wollen , wenn Sie subscribe
zurouter
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);
});
}
Winkel 4.x und höher:
Dies kann mithilfe der URL-Eigenschaft der ActivatedRoute- Klasse wie folgt erreicht werden:
this.activatedRoute.url.subscribe(url =>{
console.log(url);
});
Hinweis:
Sie müssen den Anbieter aus dem angular/router
Paket importieren und injizieren
import { ActivatedRoute } from '@angular/router`
und
constructor(private activatedRoute : ActivatedRoute){ }
Router 3.0.0-beta.2 sollte sein
this.router.events.subscribe(path => {
console.log('path = ', path);
});
In Winkel 6 und 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"
Die Antworten hier sind richtig für router-deprecated
. Für die neueste Version von router
:
this.router.changes.forEach(() => {
// Do whatever in here
});
oder
this.router.changes.subscribe(() => {
// Do whatever in here
});
Um den Unterschied zwischen den beiden zu sehen, lesen Sie bitte diese SO-Frage .
Bearbeiten
Für das Neueste müssen Sie Folgendes tun:
this.router.events.subscribe(event: Event => {
// Handle route change
});
router
wurde erneut aktualisiert (ich habe meine Antwort noch nicht aktualisiert), daher bin ich mir nicht sicher, wie es für die neueste Version ist. Für das router
, worüber ich schrieb, konnte man nicht. @akn
In Angular 8 sollten Sie mögen this.router.events.subscribe((event: Event) => {})
Beispiel:
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
}
});
}
}
In der Komponente möchten Sie möglicherweise Folgendes versuchen:
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
}
});
}
Erfassen Sie Routenänderungsereignisse auf folgende Weise ...
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;
}
}
}
});
}
}
Ort funktioniert ...
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);
}
}
Die meisten Lösungen sind korrekt, aber ich habe das Problem, dass dieses Ereignis mehrmals "Navigation emittieren" ausgelöst wird. Wenn ich eine Route geändert habe, wird dieses Ereignis ausgelöst. Hören ist also die Komplettlösung für 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 Antwort ist großartig, aber falls Sie nicht verwenden möchten, instanceof
verwenden Sie die folgenden
this.router.events.subscribe(event => {
if(event.constructor.name === "NavigationStart") {
// do something...
}
});
Auf diese Weise können Sie den aktuellen Ereignisnamen als Zeichenfolge überprüfen und bei Auftreten des Ereignisses das tun, wofür Sie Ihre Funktion geplant haben.
Event
Typ verursacht einen Fehler in Atom, deshalb habe ich ihn nicht verwendet
instanceOf
damit Ihr Beispiel auch im Produktionscode funktioniert. if(event instanceOf NavigationStart) {
if(event instanceof NavigationStart)
Ich arbeite mit der Angular5-Anwendung und stehe vor dem gleichen Problem. Wenn ich Angular Documentation durchlaufe, bieten sie die beste Lösung für die Behandlung von Router-Ereignissen. Überprüfen Sie die folgende Dokumentation.
Router-Ereignisse in Angular Route-Ereignisse in Angular5
Aber speziell für den fraglichen Fall benötigen wir NavigationEnd Event
Stellt ein Ereignis dar, das ausgelöst wird, wenn eine Navigation erfolgreich beendet wird
Wie benutzt man das?
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");
}
});
}
}
Wann soll man das benutzen?
In meinem Fall hat meine Anwendung ein gemeinsames Dashboard für alle Benutzer wie Benutzer und Administratoren, aber ich muss einige Navigationsleistenoptionen gemäß Benutzertypen anzeigen und ausblenden.
Das ist der Grund, warum ich, wenn sich die URL ändert, die Dienstmethode aufrufen muss, die die angemeldeten Benutzerinformationen gemäß der Antwort zurückgibt, weitere Vorgänge ausführen werde.
Die folgende Art von Arbeiten und kann das Knifflige für Sie tun.
// 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']);
});
Leider leitet dies später im Routing-Prozess weiter, als ich möchte. Die onActivate()
der ursprünglichen Zielkomponente wird vor der Umleitung aufgerufen.
Es gibt einen @CanActivate
Dekorator, den Sie für die Zielkomponente verwenden können, der jedoch a) nicht zentralisiert ist und b) nicht von injizierten Diensten profitiert.
Es wäre großartig, wenn jemand eine bessere Möglichkeit vorschlagen könnte, eine Route zentral zu autorisieren, bevor sie festgeschrieben wird. Ich bin sicher, es muss einen besseren Weg geben.
Dies ist mein aktueller Code (Wie würde ich ihn ändern, um die Routenänderung zu hören?):
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: '/'})]);
Ich mache es so seit RC 5
this.router.events
.map( event => event instanceof NavigationStart )
.subscribe( () => {
// TODO
} );
Nehmen Sie einfach Änderungen an AppRoutingModule vor
@NgModule({
imports: [RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled' })],
exports: [RouterModule]
})
Ich würde so etwas schreiben:
ngOnInit() {
this.routed = this.router.events.map( event => event instanceof NavigationStart )
.subscribe(() => {
} );
}
ngOnDestroy() {
this.routed.unsubscribe();
}
event._root.children[0].value._routeConfig.data
ich hoffe, dass es einen besseren Weg gibt