¿Cómo paso los datos a los componentes angulares enrutados?

En una de las plantillas de mi ruta Angular 2 ( FirstComponent ), tengo un botón

first.component.html

Pass data and route

Mi objective es lograr:

Botón clic -> ruta a otro componente mientras se conservan los datos y sin utilizar el otro componente como directiva.

Esto es lo que intenté …

PRIMERA APROXIMACIÓN

En la misma vista, estoy almacenando la misma información en función de la interacción del usuario.

first.component.ts

 export class FirstComponent { constructor(private _router: Router) { } property1: number; property2: string; property3: TypeXY; // this a class, not a primitive type // here some class methods set the properties above // DOM events routeWithData(){ // here route } } 

Normalmente dirigiría a SecondComponent por

  this._router.navigate(['SecondComponent']); 

finalmente pasando los datos por

  this._router.navigate(['SecondComponent', {p1: this.property1, p2: property2 }]); 

mientras que la definición del enlace con parámetros sería

 @RouteConfig([ // ... { path: '/SecondComponent/:p1:p2', name: 'SecondComponent', component: SecondComponent} )] 

El problema con este enfoque es que supongo que no puedo pasar datos complejos (por ejemplo, un objeto como property3) in-url;

2º ENFOQUE

Una alternativa sería incluir SecondComponent como directiva en FirstComponent.

   

Sin embargo, quiero dirigirme a ese componente, ¡no incluirlo!

ENFOQUE 3º

La solución más viable que veo aquí sería usar un servicio (por ejemplo, FirstComponentService) para

  • almacenar los datos (_firstComponentService.storeData ()) en routeWithData () en FirstComponent
  • recuperar los datos (_firstComponentService.retrieveData ()) en ngOnInit () en SecondComponent

Si bien este enfoque parece perfectamente viable, me pregunto si esta es la manera más fácil / más elegante para lograr el objective.

En general, me gustaría saber si me faltan otros enfoques potenciales para pasar los datos entre los componentes, particularmente con la menor cantidad posible de código.

actualización 4.0.0

Consulte Documentos angulares para obtener más información https://angular.io/guide/router#fetch-data-before-navigating

original

Usar un servicio es el camino a seguir. En los parámetros de enrutamiento, solo debe pasar los datos que desea reflejar en la barra de URL del navegador.

Ver también https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

El enrutador enviado con RC.4 vuelve a introducir data

 constructor(private route: ActivatedRoute) {} 
 const routes: RouterConfig = [ {path: '', redirectTo: '/heroes', pathMatch : 'full'}, {path : 'heroes', component : HeroDetailComponent, data : {some_data : 'some value'}} ]; 
 class HeroDetailComponent { ngOnInit() { this.sub = this.route .data .subscribe(v => console.log(v)); } ngOnDestroy() { this.sub.unsubscribe(); } } 

Ver también el Plunker en https://github.com/angular/angular/issues/9757#issuecomment-229847781

Creo que ya que no tenemos $ rootScope tipo de cosa en angular 2 como en angular 1.x. Podemos usar el servicio / clase angular 2 compartidos mientras en ngOnDestroy pasar los datos al servicio y después del enrutamiento tomar los datos del servicio en la función ngOnInit :

Aquí estoy usando DataService para compartir el objeto héroe:

 import { Hero } from './hero'; export class DataService { public hero: Hero; } 

Pase el objeto del primer componente de la página:

  ngOnDestroy() { this.dataService.hero = this.hero; } 

Tomar objeto del componente de la segunda página:

  ngOnInit() { this.hero = this.dataService.hero; } 

Aquí hay un ejemplo: plunker

El tercer enfoque es la forma más común de compartir datos entre componentes. Puede inyectar el servicio de artículo que desea utilizar en un componente relacionado.

 import { Injectable } from '@angular/core'; import { Predicate } from '../interfaces' import * as _ from 'lodash'; @Injectable() export class ItemsService { constructor() { } removeItemFromArray(array: Array, item: any) { _.remove(array, function (current) { //console.log(current); return JSON.stringify(current) === JSON.stringify(item); }); } removeItems(array: Array, predicate: Predicate) { _.remove(array, predicate); } setItem(array: Array, predicate: Predicate, item: T) { var _oldItem = _.find(array, predicate); if(_oldItem){ var index = _.indexOf(array, _oldItem); array.splice(index, 1, item); } else { array.push(item); } } addItemToStart(array: Array, item: any) { array.splice(0, 0, item); } getPropertyValues(array: Array, property : string) : R { var result = _.map(array, property); return result; } getSerialized(arg: any): T { return JSON.parse(JSON.stringify(arg)); } } export interface Predicate { (item: T): boolean } 

Pase usando JSON

   sample Link