AppComponent
ฉันกำลังมองหาในการตรวจสอบการเปลี่ยนแปลงในเส้นทางของฉัน
หลังจากนั้นฉันจะตรวจสอบโทเค็นผู้ใช้ทั่วโลกเพื่อดูว่าเขาเข้าสู่ระบบแล้วฉันสามารถเปลี่ยนเส้นทางผู้ใช้ถ้าเขาไม่ได้เข้าสู่ระบบ
AppComponent
ฉันกำลังมองหาในการตรวจสอบการเปลี่ยนแปลงในเส้นทางของฉัน
หลังจากนั้นฉันจะตรวจสอบโทเค็นผู้ใช้ทั่วโลกเพื่อดูว่าเขาเข้าสู่ระบบแล้วฉันสามารถเปลี่ยนเส้นทางผู้ใช้ถ้าเขาไม่ได้เข้าสู่ระบบ
คำตอบ:
ใน Angular 2 คุณสามารถsubscribe
(เหตุการณ์ Rx) ไปยังอินสแตนซ์เราเตอร์ ดังนั้นคุณสามารถทำสิ่งต่าง ๆ เช่น
class MyClass {
constructor(private router: Router) {
router.subscribe((val) => /*whatever*/)
}
}
แก้ไข (ตั้งแต่ rc.1)
class MyClass {
constructor(private router: Router) {
router.changes.subscribe((val) => /*whatever*/)
}
}
แก้ไข 2 (ตั้งแต่ 2.0.0)
ดูเพิ่มเติมที่: Router.events doc
class MyClass {
constructor(private router: Router) {
router.events.subscribe((val) => {
// see also
console.log(val instanceof NavigationEnd)
});
}
}
filter
ตัวดำเนินการRxJS router.events.pipe(filter(e => e instanceof NavigationEnd).subscribe((e) => { ... }
RxJS 6
router.events.pipe(filter(event => event instanceof NavigationStart))
ขอบคุณ Peilonrayz (ดูความคิดเห็นด้านล่าง)
เราเตอร์ใหม่> = 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
});
}
นอกจากนี้คุณยังสามารถกรองตามเหตุการณ์ที่กำหนด:
import 'rxjs/add/operator/filter';
constructor(router:Router) {
router.events
.filter(event => event instanceof NavigationStart)
.subscribe((event:NavigationStart) => {
// You only receive NavigationStart events
});
}
การใช้pairwise
โอเปอเรเตอร์เพื่อรับเหตุการณ์ก่อนหน้าและเหตุการณ์ปัจจุบันเป็นความคิดที่ดี 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
ข้อผิดพลาดเป็นเพราะในตัวอย่างตัวกรองของคุณคุณสมัครเป็นวัตถุประเภทเหตุการณ์แทน NavigationEvent
สำหรับคนที่มีมุม 7ควรเขียนดังนี้:
this.router.events.subscribe((event: Event) => {})
ตัวอย่างรายละเอียดสามารถเป็นดังนี้:
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);
}
});
}
}
เชิงมุม 7ถ้าคุณต้องการsubscribe
ที่จะrouter
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 และสูงกว่า:
สิ่งนี้สามารถทำได้โดยใช้คุณสมบัติ url ของคลาสActivatedRouteดังนี้
this.activatedRoute.url.subscribe(url =>{
console.log(url);
});
หมายเหตุ:
คุณต้องนำเข้าและฉีดผู้ให้บริการจากangular/router
แพ็คเกจ
import { ActivatedRoute } from '@angular/router`
และ
constructor(private activatedRoute : ActivatedRoute){ }
เราเตอร์ 3.0.0-beta.2 ควรเป็น
this.router.events.subscribe(path => {
console.log('path = ', path);
});
ในเชิงมุม 6 และ 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"
router-deprecated
คำตอบที่นี่เป็นที่ถูกต้องสำหรับ สำหรับเวอร์ชั่นล่าสุดrouter
:
this.router.changes.forEach(() => {
// Do whatever in here
});
หรือ
this.router.changes.subscribe(() => {
// Do whatever in here
});
หากต้องการดูความแตกต่างระหว่างทั้งสองโปรดอ่านคำถาม SOนี้
แก้ไข
สำหรับล่าสุดคุณต้องทำ:
this.router.events.subscribe(event: Event => {
// Handle route change
});
router
ได้รับการปรับปรุงใหม่อีกครั้ง (ผมยังไม่ได้รับการปรับปรุงคำตอบของฉันเลย) ดังนั้นผมไม่แน่ใจว่ามันคือสำหรับล่าสุด สำหรับrouter
ฉันเขียนถึงคุณทำไม่ได้ @akn
ใน Angular 8 คุณควรทำเช่นนั้น this.router.events.subscribe((event: Event) => {})
ตัวอย่าง:
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
}
});
}
}
ในองค์ประกอบคุณอาจต้องการลองนี้:
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
}
});
}
บันทึกเหตุการณ์การเปลี่ยนเส้นทางในลักษณะต่อไปนี้ ...
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;
}
}
}
});
}
}
สถานที่ทำงาน ...
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);
}
}
เหนือโซลูชันส่วนใหญ่ถูกต้อง แต่ฉันกำลังเผชิญหน้ากับปัญหานี้ปล่อยเหตุการณ์ 'นำทางปล่อย' หลายครั้งเมื่อฉันเปลี่ยนเส้นทางใด ๆ กิจกรรมนี้จะถูกเรียก ดังนั้นการได้ยินเป็นทางออกที่สมบูรณ์สำหรับ 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คำตอบนั้นยอดเยี่ยม แต่ในกรณีที่คุณไม่ต้องการinstanceof
ใช้สิ่งต่อไปนี้
this.router.events.subscribe(event => {
if(event.constructor.name === "NavigationStart") {
// do something...
}
});
ด้วยวิธีนี้คุณสามารถตรวจสอบชื่อเหตุการณ์ปัจจุบันเป็นสตริงและหากเหตุการณ์เกิดขึ้นคุณสามารถทำสิ่งที่คุณวางแผนที่จะทำ
Event
ประเภทที่ทำให้เกิดข้อผิดพลาดใน Atom นั่นคือเหตุผลที่ฉันไม่ได้ใช้มัน
instanceOf
ดังนั้นตัวอย่างของคุณจะทำงานในรหัสการผลิตด้วย if(event instanceOf NavigationStart) {
if(event instanceof NavigationStart)
ฉันกำลังทำงานกับแอปพลิเคชัน angular5 และฉันกำลังเผชิญกับปัญหาเดียวกัน เมื่อฉันอ่านเอกสารเชิงมุมพวกเขาให้ทางออกที่ดีที่สุดสำหรับการจัดการเราเตอร์ events.check เอกสารดังต่อไปนี้
เหตุการณ์เราเตอร์ในเหตุการณ์เส้นทางเชิงมุม ใน angular5
แต่โดยเฉพาะสำหรับกรณีที่มีปัญหาเราต้องการNavigationEnd Event
แสดงให้เห็นถึงเหตุการณ์ที่เกิดขึ้นเมื่อการนำทางจบลงด้วยความสำเร็จ
ใช้อย่างไร
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");
}
});
}
}
จะใช้เมื่อไหร่?
ในกรณีของฉันแอปพลิเคชันของฉันจะแบ่งปันแดชบอร์ดทั่วไปสำหรับผู้ใช้ทั้งหมดเช่นผู้ใช้ผู้ดูแลระบบ แต่ฉันต้องแสดงและซ่อนตัวเลือก navbar บางตัวตามประเภทผู้ใช้
นั่นเป็นเหตุผลที่เมื่อใดก็ตามที่การเปลี่ยนแปลง url ฉันจำเป็นต้องเรียกวิธีการบริการที่ส่งกลับข้อมูลผู้ใช้เข้าสู่ระบบตามการตอบสนองฉันจะไปสำหรับการดำเนินการต่อไป
ประเภทงานต่อไปนี้และอาจทำให้คุณลำบาก
// 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']);
});
น่าเสียดายที่การเปลี่ยนเส้นทางนี้ในภายหลังในกระบวนการกำหนดเส้นทางกว่าที่ฉันต้องการ onActivate()
องค์ประกอบเป้าหมายเดิมที่เรียกว่าก่อนที่จะเปลี่ยนเส้นทาง
มี @CanActivate
มัณฑนากรที่คุณสามารถใช้กับองค์ประกอบเป้าหมาย แต่นี่คือ a) ไม่รวมศูนย์และ b) ไม่ได้รับประโยชน์จากบริการที่ถูกฉีด
มันจะดีถ้าใครสามารถแนะนำวิธีที่ดีกว่าในการอนุมัติเส้นทางก่อนที่มันจะถูกส่งไป ฉันแน่ใจว่าจะต้องมีวิธีที่ดีกว่า
นี่คือรหัสปัจจุบันของฉัน (ฉันจะเปลี่ยนเพื่อฟังการเปลี่ยนเส้นทางได้อย่างไร):
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: '/'})]);
ฉันทำแบบนี้ตั้งแต่ RC 5
this.router.events
.map( event => event instanceof NavigationStart )
.subscribe( () => {
// TODO
} );
เพียงทำการเปลี่ยนแปลงใน AppRoutingModule เช่น
@NgModule({
imports: [RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled' })],
exports: [RouterModule]
})
เชิงมุม 8. ตรวจสอบว่าเส้นทางปัจจุบันเป็นเส้นทางพื้นฐานหรือไม่
baseroute: boolean;
constructor(
private router: Router,
) {
router.events.subscribe((val: any) => {
if (val.url == "/") {
this.baseroute = true;
} else {
this.baseroute = false;
}
});
}
ฉันจะเขียนสิ่งนี้:
ngOnInit() {
this.routed = this.router.events.map( event => event instanceof NavigationStart )
.subscribe(() => {
} );
}
ngOnDestroy() {
this.routed.unsubscribe();
}
คำตอบง่ายๆสำหรับ Angular 8 *
constructor(private route:ActivatedRoute) {
console.log(route);
}
event._root.children[0].value._routeConfig.data
หวังว่าจะมีวิธีที่ดีกว่านี้