Ich freue mich auf eine Routenänderung in meiner AppComponent
.
Danach werde ich das globale Benutzertoken überprüfen, um zu sehen, ob er angemeldet ist. Dann kann ich den Benutzer umleiten, falls er nicht angemeldet ist.
In Angular 2 können Sie subscribe
(Rx-Ereignis) zu einer Router-Instanz . So können Sie beispielsweise Folgendes tun
class MyClass {
constructor(private router: Router) {
router.subscribe((val) => /*whatever*/)
}
}
Edit (seit rc.1)
class MyClass {
constructor(private router: Router) {
router.changes.subscribe((val) => /*whatever*/)
}
}
Edit 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)
});
}
}
RxJS 6
router.events.pipe(filter(event => event instanceof NavigationStart))
Danke 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
});
}
Die Verwendung des Operators pairwise
zum Abrufen des vorherigen und aktuellen Ereignisses ist ebenfalls eine schöne Idee. 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); }); }; }
Für Angular 7 sollte jemand schreiben wie:
this.router.events.subscribe((event: Event) => {})
Ein detailliertes Beispiel kann wie folgt aussehen:
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);
}
});
}
}
Winkel 4.x und höher:
Dies kann mit der URL-Eigenschaft der ActivatedRoute class 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 einfügen
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*/
}
)
Die Antworten hier sind für router-deprecated
korrekt. 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, überprüfen Sie bitte diese SO - Frage .
Bearbeiten
Für das späteste müssen Sie tun:
this.router.events.subscribe(event: Event => {
// Handle route change
});
Winkel 6, wenn Sie subscribe
zu router
wollen
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);
});
}
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;
}
}
}
});
}
}
@Ludohen Die Antwort ist großartig. Falls Sie jedoch instanceof
nicht verwenden möchten, verwenden Sie Folgendes
this.router.events.subscribe(event => {
if(event.constructor.name === "NavigationStart") {
// do something...
}
});
auf diese Weise können Sie den Namen des aktuellen Ereignisses als Zeichenfolge überprüfen und wenn das Ereignis aufgetreten ist, können Sie tun, was Sie für Ihre Funktion geplant haben.
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
}
});
}
Ich arbeite mit der Anwendung angle5 und ich stehe vor demselben Problem. Wenn ich die Angular-Dokumentation durchsehe, bieten sie die beste Lösung für den Umgang mit Router-Ereignissen. Überprüfen Sie die folgende Dokumentation.
Router-Ereignisse in Angular Routenereignisse in angle5
Aber speziell für den jeweiligen 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 benutzt man das?
In meinem Fall gibt es für meine Anwendung ein gemeinsames Dashboard für alle Benutzer, z. B. Benutzer, Administratoren. Ich muss jedoch einige Navbar-Optionen je nach Benutzertyp anzeigen und ausblenden.
Aus diesem Grund muss bei jeder Änderung der URL die Servicemethode aufgerufen werden, die als Antwort angemeldete Benutzerinformationen zurückgibt. Ich werde weitere Operationen ausführen.
über den meisten Lösungen korrekt, aber ich stehe vor dem Problem, dass dieses Ereignis mehrmals ausgegeben wird. Das Ereignis "Navigation emit" wird ausgelöst. Also hören Sie die komplette Lö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();
}
}
Ich mache das seit RC 5 so
this.router.events
.map( event => event instanceof NavigationStart )
.subscribe( () => {
// TODO
} );
Die folgende Art von Arbeiten und kann das schwierigste 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 um, als ich möchte. Die onActivate()
der ursprünglichen Zielkomponente wird vor der Weiterleitung aufgerufen.
Es gibt einen @CanActivate
-Dekorator, den Sie für die Zielkomponente verwenden können. Dies ist jedoch a) nicht zentralisiert und b) profitiert nicht von injizierten Services.
Es wäre großartig, wenn jemand eine bessere Möglichkeit vorschlagen könnte, eine Route zentral zu autorisieren, bevor sie festgelegt wird. Ich bin sicher, dass es einen besseren Weg geben muss.
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: '/'})]);
Nehmen Sie einfach Änderungen an AppRoutingModule vor
@NgModule({
imports: [RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled' })],
exports: [RouterModule]
})