Enviar datos a través de rutas de enrutamiento en Angular

182

¿Hay alguna forma de enviar datos como parámetro con router.navigate? Quiero decir, algo como este ejemplo, como puedes ver, la ruta tiene un parámetro de datos, pero al hacer esto no funciona:

this.router.navigate(["heroes"], {some-data: "othrData"})

porque algunos datos no son un parámetro válido. ¿Cómo puedo hacer eso? No quiero enviar el parámetro con queryParams.

Motomine
fuente
Creo que debería ser de otra manera como en AngularJS, donde pudimos hacer algo como $ state.go ('heroes', {some-data: "otherData"})
Motomine
3 formas simples de compartir datos a través de rutas - angulartutorial.net/2017/12/…
Prashobh
Use mi enfoque npmjs.com/package/ngx-navigation-with-data último comentario de mí, lo mejor para todos
Virendra Yadav

Respuestas:

517

Hay mucha confusión sobre este tema porque hay muchas formas diferentes de hacerlo.

Estos son los tipos apropiados utilizados en las siguientes capturas de pantalla:

private route: ActivatedRoute
private router: Router

1) Parámetros de enrutamiento necesarios:

ingrese la descripción de la imagen aquí

2) Parámetros opcionales de ruta:

ingrese la descripción de la imagen aquí

3) Parámetros de consulta de ruta:

ingrese la descripción de la imagen aquí

4) Puede usar un servicio para pasar datos de un componente a otro sin usar parámetros de ruta.

Para ver un ejemplo, consulte: https://blogs.msmvps.com/deborahk/build-a-simple-angular-service-to-share-data/

Tengo un plunker de esto aquí: https://plnkr.co/edit/KT4JLmpcwGBM2xdZQeI9?p=preview

DeborahK
fuente
¡Gracias por su respuesta! ¿Cuál es la diferencia entre 2) y 3)? Porque ambos terminan agregando "? Parameter =" en la URL. ¿Me podría dar un ejemplo para el 4)? No puedo entender cómo hacerlo.
Motomine 01 de
Actualicé por respuesta para mostrar las diferentes URL y proporcionar un enlace a una publicación de blog y un plunker sobre cómo pasar datos con un servicio. La URL es diferente con parámetros opcionales y de consulta como se muestra arriba. Además, los parámetros de consulta se pueden conservar a través de las rutas.
DeborahK
66
También tengo un curso de Pluralsight sobre enrutamiento que cubre todo esto: app.pluralsight.com/library/courses/angular-routing/… /... Puede inscribirse en una semana gratis si está interesado en obtener más información.
DeborahK
3
Los datos solo se "comparten" dentro de la aplicación en ejecución. Si el usuario actualiza la página, toda la aplicación se vuelve a cargar desde el servidor, por lo que no se conserva ningún estado anterior en la aplicación. Pensarlo en términos de una aplicación normal, cuando un usuario actualiza es como cerrar y volver a abrir la aplicación. Si necesita conservar el estado después de una actualización, deberá almacenarlo en algún lugar, como almacenamiento local o en el servidor.
DeborahK
2
Solo una pequeña pista: el routetipo es ActivatedRoute, no Router.
Arsen Khachaturyan
156

Hay un nuevo método que vino con Angular 7.2.0

https://angular.io/api/router/NavigationExtras#state

Enviar:

this.router.navigate(['action-selection'], { state: { example: 'bar' } });

Recibir:

constructor(private router: Router) {
  console.log(this.router.getCurrentNavigation().extras.state.example); // should log out 'bar'
}

Puede encontrar información adicional aquí:

https://github.com/angular/angular/pull/27198

El enlace de arriba contiene este ejemplo, lo que puede ser útil: https://stackblitz.com/edit/angular-bupuzn

Véger Lóránd
fuente
11
Esta es la respuesta correcta dadas las nuevas características en Angular 7.
Randy
2
Con este enfoque, ¿cómo manejaría una actualización del navegador por parte del usuario? En ese caso, los datos en los extras de navegación parecen desaparecer, por lo que no hay posibilidad de usarlos nuevamente en la actualización.
tobi_b
1
@tobi_b Creo que tienes razón, después de actualizar no puedes alcanzarlo. Si lo necesita después de actualizar, los métodos en la respuesta aceptada serán mejores.
Véger Lóránd
3
Sí, es por eso que solo puede obtener los datos de this.router.getCurrentNavigation () en el constructor. Si lo necesita en otro lugar, como ngOnInit (), puede acceder a los datos a través de "history.state". De la documentación: "Estado pasado a cualquier navegación. Este valor será accesible a través del objeto adicional devuelto por router.getCurrentNavigation () mientras se está ejecutando una navegación. Una vez que se completa una navegación, este valor se escribirá en history.state cuando la ubicación Se llama al método .go o location.replaceState antes de activar esta ruta ".
Véger Lóránd
8
También asegúrese de que no trate de recibir un objeto de extras en el ngOnInit()quethis.router.getCurrentNavigation().extras
hastrb
26

La última versión de angular (7.2 +) ahora tiene la opción de pasar información adicional usando NavigationExtras .

Componente de inicio

import {
  Router,
  NavigationExtras
} from '@angular/router';
const navigationExtras: NavigationExtras = {
  state: {
    transd: 'TRANS001',
    workQueue: false,
    services: 10,
    code: '003'
  }
};
this.router.navigate(['newComponent'], navigationExtras);

nuevoComponente

test: string;
constructor(private router: Router) {
  const navigation = this.router.getCurrentNavigation();
  const state = navigation.extras.state as {
    transId: string,
    workQueue: boolean,
    services: number,
    code: string
  };
  this.test = "Transaction Key:" + state.transId + "<br /> Configured:" + state.workQueue + "<br /> Services:" + state.services + "<br /> Code: " + state.code;
}

Salida

ingrese la descripción de la imagen aquí

Espero que esto ayude!

dev-nish
fuente
1

@ dev-nish Su código funciona con pequeños ajustes en ellos. hacer el

const navigationExtras: NavigationExtras = {
  state: {
    transd: 'TRANS001',
    workQueue: false,
    services: 10,
    code: '003'
  }
};

dentro

let navigationExtras: NavigationExtras = {
  state: {
    transd: '',
    workQueue: ,
    services: ,
    code: ''
  }
};

entonces, si desea enviar específicamente un tipo de datos, por ejemplo, JSON como resultado de un formulario, puede enviar los datos de la misma manera que se explicó anteriormente.

Saurav Mohan V
fuente
0

En navigationExtra podemos pasar solo un nombre específico como argumento; de lo contrario, muestra un error como el siguiente: Por ejemplo, aquí quiero pasar la clave del cliente en la navegación del enrutador y paso así:

this.Router.navigate(['componentname'],{cuskey: {customerkey:response.key}});

pero muestra algún error como el siguiente:

Argument of type '{ cuskey: { customerkey: any; }; }' is not assignable to parameter of type 'NavigationExtras'.
  Object literal may only specify known properties, and 'cuskey' does not exist in type 'NavigationExt## Heading ##ras'

.

Solución: tenemos que escribir así:

this.Router.navigate(['componentname'],{state: {customerkey:response.key}});
A. PRABIN SARAB
fuente
-2

Lo mejor que encontré en Internet para esto es ngx-navigation-with-data . Es muy simple y bueno para navegar los datos de un componente a otro componente. Solo tiene que importar la clase de componente y usarla de manera muy simple. Supongamos que tiene un hogar y un componente y desea enviar datos

COMPONENTE DEL HOGAR

import { Component, OnInit } from '@angular/core';
import { NgxNavigationWithDataComponent } from 'ngx-navigation-with-data';

@Component({
 selector: 'app-home',
 templateUrl: './home.component.html',
 styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

constructor(public navCtrl: NgxNavigationWithDataComponent) { }

 ngOnInit() {
 }

 navigateToABout() {
  this.navCtrl.navigate('about', {name:"virendta"});
 }

}

Sobre el componente

import { Component, OnInit } from '@angular/core';
import { NgxNavigationWithDataComponent } from 'ngx-navigation-with-data';

@Component({
 selector: 'app-about',
 templateUrl: './about.component.html',
 styleUrls: ['./about.component.css']
})
export class AboutComponent implements OnInit {

 constructor(public navCtrl: NgxNavigationWithDataComponent) {
  console.log(this.navCtrl.get('name')); // it will console Virendra
  console.log(this.navCtrl.data); // it will console whole data object here
 }

 ngOnInit() {
 }

}

Para cualquier consulta, siga https://www.npmjs.com/package/ngx-navigation-with-data

Comenta abajo para pedir ayuda.

Virendra Yadav
fuente
¿Transfiere datos en forma de parámetros o simplemente en segundo plano?
Marium Malik
No pude entender @MariumMalik ¿Puedes preguntar de manera descriptiva?
Virendra Yadav
Sí, lo hace @MariumMalik
Virendra Yadav
3
¿Parece ser el autor de esto, en lugar de "Lo encontré en Internet"? También se le pide que no envíe spam en el hilo Angular 7 que implementa una funcionalidad similar ( github.com/angular/angular/pull/27198 )
IrishDubGuy