Cómo detectar un cambio de ruta en Angular?


Estoy buscando detectar un cambio de ruta en mi AppComponent.

A partir de entonces voy a comprobar el token de usuario global para ver si está conectado. Entonces puedo redirigir al usuario si no está conectado.

 221
Author: Lazar Ljubenović, 2015-11-04

11 answers

En Angular 2 puede subscribe (evento Rx) a una instancia de enrutador. Así que puedes hacer cosas como

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

Editar (desde rc.1)

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

Editar 2 (desde 2.0.0)

Véase también : Router.eventos doc

class MyClass {
  constructor(private router: Router) {
    router.events.subscribe((val) => {
        // see also 
        console.log(val instanceof NavigationEnd) 
    });
  }
}
 288
Author: Ludohen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-13 14:31:55

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

También puede filtrar por el evento dado:

import 'rxjs/add/operator/filter';

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

Usando el pairwise operator para obtener el evento anterior y actual también es una buena idea. 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);
        });
    };
}
 214
Author: Günter Zöchbauer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-22 12:54:39

Angular 4.x y superiores :

Esto se puede lograr usando la propiedad url de la clase ActivatedRoute como se muestra a continuación,

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

Nota: Que necesita importar e inyectar el proveedor desde angular/router paquete

import { ActivatedRoute } from '@angular/router`

Y

constructor(private activatedRoute : ActivatedRoute){  }
 29
Author: Aravind,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-31 07:47:37

Router 3.0.0-beta.2 debe ser

this.router.events.subscribe(path => {
  console.log('path = ', path);
});
 14
Author: Mike Lallemont,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-06 16:52:40

Las respuestas aquí son correctas para router-deprecated. Para la última versión de router:

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

O

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

Para ver la diferencia entre los dos, por favor echa un vistazo esta pregunta SO.

Editar

Para la última debe hacer:

this.router.events.subscribe(event: Event => {
    // Handle route change
});
 11
Author: Dehli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:02:48

En angular 6 y 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*/
}
)
 10
Author: JBRandri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-15 13:12:33

Capture eventos de cambio de ruta de la siguiente manera...

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
Author: Narottam Goyal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-20 09:36:43

@Ludohen la respuesta es genial, pero en caso de que no quieras usar instanceof usa lo siguiente

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

De esta manera puede verificar el nombre del evento actual como una cadena y si el evento ocurrió, puede hacer lo que planeó hacer su función.

 1
Author: Khaled Al-Ansari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-05 10:25:59

El siguiente TIPO de obras y puede hacer el difícil para usted.

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

Desafortunadamente esto redirige más tarde en el proceso de enrutamiento de lo que me gustaría. El onActivate() del componente de destino original se llama antes de la redirección.

Hay un decorador @CanActivate que puede usar en el componente de destino, pero esto a) no es centralizado y b) no se beneficia de los servicios inyectados.

Sería genial si alguien puede sugerir una mejor manera de autorizar centralmente una ruta antes de que sea comprometido. Estoy seguro de que debe haber una mejor manera.

Este es mi código actual (¿Cómo lo cambiaría para escuchar el cambio de ruta?):

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
Author: Richard Evans,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-05 10:30:07

Lo hago así desde RC 5

this.router.events
  .map( event => event instanceof NavigationStart )
  .subscribe( () => {
    // TODO
  } );
 0
Author: jirigracik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-25 13:14:30

Estoy trabajando con la aplicación angular5 y me enfrento al mismo problema . cuando paso por la documentación de Angular, proporcionan la mejor solución para el manejo de eventos de enrutador.compruebe la siguiente documentación.

Representa un evento activado cuando una navegación termina correctamente

Cómo usar esto ?

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

¿Cuándo usar esto ?

En mi caso , mi aplicación comparte un panel de control común para todos los usuarios , como usuarios, Administradores, pero necesito mostrar y ocultar algunas opciones de la barra de navegación según los tipos de usuario.

Es por eso que cada vez que cambia la url, necesito llamar al método de servicio que devuelve la información del usuario registrada según la respuesta, iré a realizar más operaciones.

 0
Author: Bhagvat Lande,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-10-06 10:41:37