Jawaban:
Dalam Angular 2 Anda dapat subscribe
(acara Rx) ke instance Router. Jadi Anda bisa melakukan hal-hal seperti
class MyClass {
constructor(private router: Router) {
router.subscribe((val) => /*whatever*/)
}
}
Edit (sejak rc.1)
class MyClass {
constructor(private router: Router) {
router.changes.subscribe((val) => /*whatever*/)
}
}
Edit 2 (sejak 2.0.0)
lihat juga: Router.events doc
class MyClass {
constructor(private router: Router) {
router.events.subscribe((val) => {
// see also
console.log(val instanceof NavigationEnd)
});
}
}
filter
operator RxJS . router.events.pipe(filter(e => e instanceof NavigationEnd).subscribe((e) => { ... }
RxJS 6
router.events.pipe(filter(event => event instanceof NavigationStart))
Terima kasih kepada Peilonrayz (lihat komentar di bawah)
router baru> = 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
});
}
Anda juga dapat memfilter berdasarkan peristiwa yang diberikan:
import 'rxjs/add/operator/filter';
constructor(router:Router) {
router.events
.filter(event => event instanceof NavigationStart)
.subscribe((event:NavigationStart) => {
// You only receive NavigationStart events
});
}
Menggunakan pairwise
operator untuk mendapatkan acara sebelumnya dan saat ini juga merupakan ide bagus. 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
kesalahannya adalah karena dalam cuplikan filter Anda, Anda berlangganan objek bertipe Event alih-alih NavigationEvent.
Untuk Angular 7 seseorang harus menulis seperti:
this.router.events.subscribe((event: Event) => {})
Contoh terperinci dapat sebagai berikut:
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);
}
});
}
}
Sudut 7 , jika Anda ingin subscribe
untukrouter
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);
});
}
4.x sudut ke atas:
Ini dapat dicapai menggunakan properti url dari kelas ActivatedRoute seperti di bawah ini,
this.activatedRoute.url.subscribe(url =>{
console.log(url);
});
Catatan:
Anda perlu mengimpor dan menyuntikkan penyedia dari angular/router
paket
import { ActivatedRoute } from '@angular/router`
dan
constructor(private activatedRoute : ActivatedRoute){ }
Router 3.0.0-beta.2 seharusnya
this.router.events.subscribe(path => {
console.log('path = ', path);
});
Dalam angular 6 dan 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"
Jawabannya di sini benar router-deprecated
. Untuk versi terbaru router
:
this.router.changes.forEach(() => {
// Do whatever in here
});
atau
this.router.changes.subscribe(() => {
// Do whatever in here
});
Untuk melihat perbedaan antara keduanya, silakan lihat pertanyaan SO ini .
Edit
Untuk yang terbaru harus Anda lakukan:
this.router.events.subscribe(event: Event => {
// Handle route change
});
router
telah diperbarui lagi (saya belum memperbarui jawaban saya belum), jadi saya tidak yakin bagaimana itu adalah untuk yang terbaru. Untuk yang router
saya tulis, Anda tidak bisa. @akn
Di Angular 8 Anda harus suka this.router.events.subscribe((event: Event) => {})
Contoh:
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
}
});
}
}
Dalam komponen, Anda mungkin ingin mencoba ini:
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
}
});
}
Tangkap acara perubahan rute dengan cara berikut ...
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;
}
}
}
});
}
}
Lokasi berhasil ...
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);
}
}
di atas sebagian besar solusi yang benar, tetapi saya menghadapi masalah ini memancarkan beberapa kali acara 'Navigasi memancarkan'. Ketika saya mengubah rute apa pun peristiwa ini dipicu. Jadi dengar adalah solusi lengkap untuk 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 jawaban bagus, tetapi jika Anda tidak ingin menggunakan instanceof
gunakan yang berikut ini
this.router.events.subscribe(event => {
if(event.constructor.name === "NavigationStart") {
// do something...
}
});
dengan cara ini Anda dapat memeriksa nama acara saat ini sebagai string dan jika acara tersebut terjadi, Anda dapat melakukan apa yang Anda rencanakan untuk dilakukan.
Event
tipe ini menyebabkan kesalahan pada Atom itu sebabnya saya tidak menggunakannya
instanceOf
sehingga contoh Anda akan bekerja dalam kode produksi juga. if(event instanceOf NavigationStart) {
if(event instanceof NavigationStart)
Saya bekerja dengan aplikasi angular5 dan saya menghadapi masalah yang sama. ketika saya pergi melalui Dokumentasi Sudut mereka memberikan solusi terbaik untuk menangani peristiwa router. periksa dokumentasi berikut.
Perute Router dalam Peristiwa Rute Sudut di angular5
Tetapi khusus untuk kasus ini memberikan pertanyaan yang kita butuhkan Acara NavigationEnd
Merupakan acara yang dipicu ketika navigasi berakhir dengan sukses
Bagaimana cara menggunakan ini?
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");
}
});
}
}
Kapan harus menggunakan ini?
Dalam kasus saya, aplikasi saya berbagi dasbor umum untuk semua pengguna seperti pengguna, Admin, tetapi saya perlu menunjukkan dan menyembunyikan beberapa opsi navbar sesuai jenis pengguna.
Itu sebabnya setiap kali perubahan url saya perlu memanggil metode layanan yang mengembalikan informasi pengguna yang masuk sebagai tanggapan saya akan pergi untuk operasi lebih lanjut.
JENIS pekerjaan berikut dan mungkin melakukan trik untuk Anda.
// 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']);
});
Sayangnya ini pengalihan kemudian dalam proses routing dari yang saya inginkan. The onActivate()
komponen target semula disebut sebelum redirect.
Ada @CanActivate
dekorator yang dapat Anda gunakan pada komponen target tetapi ini a) tidak terpusat dan b) tidak mendapat manfaat dari layanan yang disuntikkan.
Alangkah baiknya jika ada yang bisa menyarankan cara yang lebih baik untuk otorisasi rute secara terpusat sebelum dilakukan. Saya yakin pasti ada cara yang lebih baik.
Ini adalah kode saya saat ini (Bagaimana saya mengubahnya untuk mendengarkan perubahan rute?):
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: '/'})]);
Saya melakukannya seperti ini sejak RC 5
this.router.events
.map( event => event instanceof NavigationStart )
.subscribe( () => {
// TODO
} );
Buat saja perubahan di AppRoutingModule suka
@NgModule({
imports: [RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled' })],
exports: [RouterModule]
})
Saya akan menulis sesuatu seperti ini:
ngOnInit() {
this.routed = this.router.events.map( event => event instanceof NavigationStart )
.subscribe(() => {
} );
}
ngOnDestroy() {
this.routed.unsubscribe();
}
event._root.children[0].value._routeConfig.data
saya berharap ada cara yang lebih baik