Відповіді:
У 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/isissue/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
помилка в тому, що у вашому фрагменті фільтра ви підписуєтесь на об’єкт типу Event замість NavigationEvent.
Для Angular 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 класу ActivateRoute, як показано нижче,
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
У куті 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);
}
}
вище більшість рішень правильні, але я зіткнувся з проблемою цього випромінювання кілька разів "Навігація випромінювати" event.when я змінив будь-який маршрут, ця подія запускається. Тому чути - це повне рішення для 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, і я стикаюся з тим же питанням. коли я проходжу кутову документацію, вони пропонують найкраще рішення для обробки маршрутизатора подій. Перевірте наступну документацію.
Події маршрутизатора в кутовому маршруті події в кутовій5
Але спеціально для випадку, про який йдеться, нам потрібен 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");
}
});
}
}
Коли це використовувати?
У моєму випадку мій додаток ділиться загальною інформаційною панеллю для всіх користувачів, таких як користувачі, адміністратори, але мені потрібно показати та приховати деякі параметри навігації відповідно до типів користувача.
Ось чому щоразу, коли змінюється 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
декоратор, який ви можете використовувати для цільового компонента, але це а) не централізовано та б) не отримує користі від введених послуг.
Було б чудово, якщо хтось може запропонувати кращий спосіб централізованого авторизації маршруту до його здійснення. Я впевнений, що повинен бути кращий спосіб.
Це мій поточний код (як я міг би змінити його, щоб слухати зміну маршруту?):
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]
})
Я б написав щось подібне:
ngOnInit() {
this.routed = this.router.events.map( event => event instanceof NavigationStart )
.subscribe(() => {
} );
}
ngOnDestroy() {
this.routed.unsubscribe();
}
event._root.children[0].value._routeConfig.data
сподіваюся, що може бути і кращий спосіб