web-dev-qa-db-fra.com

Comment détecter un changement de route en angulaire?

Je cherche à détecter un changement d'itinéraire dans ma AppComponent.

Ensuite, je vérifierai si le jeton de l'utilisateur global est connecté. Ensuite, je pourrai rediriger l'utilisateur s'il n'est pas connecté.

265
AngularM

Dans Angular 2, vous pouvez subscribe (événement Rx) en fonction d’une instance de routeur.

class MyClass {
  constructor(private router: Router) {
    router.subscribe((val) => /*whatever*/)
  }
}

Edit (depuis rc.1)

class MyClass {
  constructor(private router: Router) {
    router.changes.subscribe((val) => /*whatever*/)
  }
}

Edit 2 (depuis 2.0.0)

voir aussi: Router.events doc

class MyClass {
  constructor(private router: Router) {
    router.events.subscribe((val) => {
        // see also 
        console.log(val instanceof NavigationEnd) 
    });
  }
}
344
Ludohen

RxJS 6

router.events.pipe(filter(event => event instanceof NavigationStart))

Merci à Peilonrayz (voir les commentaires ci-dessous)

nouveau routeur> = 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
  });
}

Vous pouvez également filtrer par événement donné: 

import 'rxjs/add/operator/filter';

constructor(router:Router) {
  router.events
    .filter(event => event instanceof NavigationStart)
    .subscribe((event:NavigationStart) => {
      // You only receive NavigationStart events
    });
}

Utiliser l'opérateur pairwise pour obtenir l'événement précédent et actuel est également une bonne idée. 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);
        });
    };
}
252
Günter Zöchbauer

Angulaire 4.x et ci-dessus: 

Ceci peut être réalisé en utilisant la propriété url de ActivatedRoute class comme ci-dessous,

this.activatedRoute.url.subscribe(url =>{
     console.log(url);
});

Note: Il vous faut importer et injecter le fournisseur depuis le package angular/router

import { ActivatedRoute } from '@angular/router`

et 

constructor(private activatedRoute : ActivatedRoute){  }
35
Aravind

Le routeur 3.0.0-beta.2 devrait être

this.router.events.subscribe(path => {
  console.log('path = ', path);
});
16
Mike Lallemont

En angulaire 6 et 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*/
}
)
15
JBRandri

Les réponses ici sont correctes pour router-deprecated . Pour la dernière version de router :

this.router.changes.forEach(() => {
    // Do whatever in here
});

ou

this.router.changes.subscribe(() => {
     // Do whatever in here
});

Pour voir la différence entre les deux, veuillez vérifier cette question SO .

Modifier

Pour le plus tard, vous devez faire: 

this.router.events.subscribe(event: Event => {
    // Handle route change
});
13
Dehli

Angulaire 6, si vous voulez 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);
  });
}
10
Druta Ruslan

Capturez les événements de changement d'itinéraire de la manière suivante ... 

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;
                }
                }
            }
        });
    }
}
5
Narottam Goyal

@Ludohen answer est génial, mais si vous ne voulez pas utiliser instanceof, utilisez ce qui suit

this.router.events.subscribe(event => {
  if(event.constructor.name === "NavigationStart") {
    // do something...
  }
});

de cette façon, vous pouvez vérifier le nom de l'événement en cours sous forme de chaîne et si l'événement se produit, vous pouvez effectuer les tâches que vous avez prévues. 

2
Khaled Al-Ansari

Dans le composant, vous voudrez peut-être essayer ceci:

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
            }
        });
}
1
mojtaba ramezani

Je travaille avec l'application angular5 et je suis confronté au même problème. Lorsque je consulte la documentation angulaire, ils fournissent la meilleure solution pour gérer les événements de routeur.check après la documentation.

Représente un événement déclenché lorsqu'une navigation se termine avec succès

Comment l'utiliser?

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");
            }
        });
    }
}

Quand utiliser ceci?

Dans mon cas, mon application partage un tableau de bord commun pour tous les utilisateurs, tels que les utilisateurs, les administrateurs, mais je dois afficher et masquer certaines options de la barre de navigation en fonction du type d'utilisateur.

C’est pourquoi, chaque fois que l’URL change, j’ai besoin d’appeler une méthode de service qui renvoie les informations de l’utilisateur connecté conformément à la réponse.

1
Bhagvat Lande

au-dessus de la plupart des solutions correctes, mais je suis confronté à ce problème émettre plusieurs fois «Navigation émettre» événement. Alors entendez est la solution complète pour 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();
  }
} 
1
yala ramesh

Je le fais comme ça depuis la RC 5

this.router.events
  .map( event => event instanceof NavigationStart )
  .subscribe( () => {
    // TODO
  } );
0
jirigracik

Le type suivant de travaux et peut faire le difficile pour vous.

// 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']);
    });

Malheureusement, cette redirection plus tard que je le souhaiterais dans le processus de routage. La onActivate() du composant cible d'origine est appelée avant la redirection.

Il existe un décorateur @CanActivate que vous pouvez utiliser sur le composant cible, mais il s'agit a) non centralisé et b) ne bénéficie pas des services injectés.

Ce serait formidable si quelqu'un pouvait suggérer un meilleur moyen d'autoriser de manière centralisée un itinéraire avant qu'il ne soit engagé. Je suis sûr qu'il doit y avoir un meilleur moyen.

Ceci est mon code actuel (comment pourrais-je le changer pour écouter le changement de route?):

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: '/'})]);
0
Richard Evans

Apportez des modifications sur AppRoutingModule comme

@NgModule({
imports: [RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled' })],
  exports: [RouterModule]
})
0
Pullat Junaid